我需要一个非常非常大的数字(143百万位)进行压缩。我正在寻找一种压缩它的解决方案,而不会损失至少10%。我已经尝试过zlib,zipfile,gzip等等,但这些都不会真正压缩这个数字。所以这是我的想法,但问题是我不知道如何实现它
首先,我有号码。
234512
然后我必须将它分成小于256的数字块。
234,51,2
如果尺寸固定(例如,总是3位数),我可以拆分它,但每块可能有1,2或3位数,所以我被困在这里。
在我得到小于256的数字块后,我会将它们变成字符并写入文件。
编辑:由于使用该方法我将失去着陆零,我创建了一个压缩数字大小的50%的算法:
由于我只有0-9个数字作为数字,我可以说它们是十六进制的(尽管它们不是)并转换为基数10,从而减小了它的大小。编辑2:跳过这一步。实际上,这样做只会增加它的大小!
我会得到一个较小的数字,0-9数字作为数字,然后我可以再次假设它们是十六进制的。因此,使用unhexlify将其转换为大量字节的一半! (如果它是奇数长度,在附加到数字处添加'a')
代码:
if len(o)%2: o+='a' #avoid odd-length
return unhexlify(o)
我甚至可以用zlib压缩返回数据。总压缩率为45%。
答案 0 :(得分:1)
这里是:
#! /usr/bin/python
n = 313105074639950943116 #just an example
#your algorithm
chars = []
buff = ''
s = str (n)
while s:
if int (buff + s [0] ) < 256:
buff += s [0]
s = s [1:]
else:
chars.append (int (buff) )
buff = ''
if buff: chars.append (int (buff) )
print ('You need to write these numbers converted to chars: {}'.format (chars) )
print ('This are {} bytes of data.'.format (len (chars) ) )
print ('But you cannot decompress it, because you lose leading zeros.')
chars = []
while n:
chars.append (n & 0xff)
n = n >> 8
print ('Now if you just write the number to a file without your algorithm:')
print ('You need to write these numbers converted to chars: {}'.format (chars) )
print ('This are {} bytes of data.'.format (len (chars) ) )
print ('And you can actually read it again.')
编辑:如果你的数字的十进制表示有很多6s和8s的序列,你应该尝试使用十进制表示的RLE,也许与霍夫曼树结合。
编辑2 :考虑(a)6s和8s的长时间运行,以及(b)你不想使用某些既定算法的事实,你可以使用这样一些非常粗略的RLE :
#! /usr/bin/python
n = 313666666666666688888888888888888866666666666666666666666666666610507466666666666666666666666666399509431888888888888888888888888888888888888888888881666666666666
s = str (n)
print (s)
comp = ''
count = None
while s:
if s [0] in '01234579':
if count:
comp += ('<{}>' if count [0] == 6 else '[{}]').format (count [1] )
count = None
comp += s [0]
if s [0] == '6':
if count and count [0] == 6: count = (6, count [1] + 1)
elif count:
comp += ('[{}]').format (count [1] )
count = (6, 1)
else: count = (6, 1)
if s [0] == '8':
if count and count [0] == 8: count = (8, count [1] + 1)
elif count:
comp += ('<{}>').format (count [1] )
count = (8, 1)
else: count = (8, 1)
s = s [1:]
if count: comp += ('<{}>' if count [0] == 6 else '[{}]').format (count [1] )
print (comp)