4位编码器/解码器
用于更高效地存储 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日:初始版本