65.9K
CodeProject 正在变化。 阅读更多。
Home

4位编码器/解码器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.38/5 (4投票s)

2019年2月6日

CPOL
viewsIcon

20234

用于更高效地存储 15 种不同符号的 4 位编码器代码

引言

将8位字符串转换为4位字符串(最多允许15个不同的字符)。

相应地:将两个8位字符串转换为一个8位字符串。

通过这种转换,字符串可以使用通常string大小的一半来存储。这对于使用最多15个不同字符的大量数据可能很有用(例如电话号码)。

背景

我一直在想,将电话号码作为string存储在数据库中是一种浪费内存的行为。但将其存储为整数也不可行。我的解决方案是使用编码的string

Using the Code

下面,您可以看到类的实现。在底部,有一个test()函数,展示了如何使用这段代码。

要自定义可以表示/编码的符号,请更改Encode4Bits._mappingTable。切勿使用超过15个自定义值。

class Encode4Bits:
    def __init__(self):
        # first element is always "END"
        self._mappingTable = ['\0', \
                              '0','1','2','3','4','5','6','7','8','9', \
                              '-','','','','']

    def _encodeCharacter(self,char):
        """@return index of element or None, if not exists"""
        for p in range(len(self._mappingTable)):
            if(char == self._mappingTable[p]):
                return p
        return None

    def encode(self, string):
        strLen = len(string)

        # ===== 1. map all chars to an index in our table =====
        mappingIndices = []
        for i in range(strLen):
            char = string[i]
            index = self._encodeCharacter(char)
            if(index is None):
                raise("ERROR: Could not encode '" + char + "'.")
            mappingIndices.append(index)
        mappingIndices.append(0)
        
        # ===== 2. Make num values even =====
        # 4 bit => 2 chars in one byte. Therefore: need even num values
        if(len(mappingIndices) % 2 != 0):
            mappingIndices.append(0)

        # ===== 3. create string =====
        ret = ""
        i = 0
        while True:
            if(i >= len(mappingIndices)):
                break # finished
            val1 = mappingIndices[i]
            val2 = mappingIndices[i+1]
            val1 = val1 << 4           
            mixed = val1 | val2
            char = chr(mixed)
            ret += str(char)
            i += 2

        return ret

    def decode(self, string):
        ret = ""
        for char in string:
            index1 = (ord(char) & 0xF0) >> 4
            index2 = (ord(char) & 0x0F)            
            ret += self._mappingTable[index1]
            ret += self._mappingTable[index2]
        
        return ret

def test():
    numberCompressor = Encode4Bits()
    encoded = numberCompressor.encode("067-845-512")
    decoded = numberCompressor.decode(encoded)
    print(len(decoded))
    print(len(encoded))


if __name__ == "__main__":
    test()

历史

  • 2019年2月8日:初始版本
© . All rights reserved.