我遇到如何将huffman编码字符串转换为二进制python的问题。
这个问题不涉及霍夫曼算法。
就像这样:
我可以得到一个编码的霍夫曼字符串,比如01010101010
。 注意,它是一个字符串。
但现在我想将字符串表示保存为真正的二进制文件。
在霍夫曼编码的字符串中,每0和1都是字节。
我想要的是每0和1是位。
我怎么能在python中做到这一点?
修改1:
请原谅我没有说清楚我的问题。
让我解释一下我目前写入零和一些二进制文件的方法。
说,我们可以使用代码字符串s ='010101010'。
int
将其转换为整数unichr
将其转换为字符串,以便我可以将其写入文件另外需要注意的是,我需要读取文件才能解码霍夫曼代码。
所以我的方法是,
在第2步,问题发生了,我变得一无所知。
由于某些霍夫曼字符串可能很短(例如,10
),而有些字符串可能很长(010101010101001
)。这导致它们的int值中的字节长度不同(
一些短字符串可能只需要一个字节,而长字符串可以采用两个甚至更多
)
以下代码说明了我的问题:
ss=['010101','10010101010']
# first one is short and takes only one byte in its int value
# second one is long and takes two bytes
print 'write it to file'
with open('binary.bin','wb') as f:
for s in ss:
n=int(s,2)
print n
s=unichr(n)
f.write(s)
print 'read it to file'
with open('binary.bin','rb') as f:
for s in f.read():
print ord(s)
我在第二个带有部分的中读取一个字节,但这实际上是不正确的。因为字符串10010101010
占用两个字节。
所以,当我从文件中读取这些字节时,我应该一次读取多少字节?
答案 0 :(得分:2)
您可能希望在Python中使用两种不同的“二进制”表示形式。
一个是“bignum”或任意精度整数。此类型在Python 2.x中称为long
,在Python 3.x中称为int
。顾名思义,这种表示在语义上是一个任意长度的整数,所以如果你计划对结果数进行算术运算,它就很有用。要解析一串二进制数字,请使用
# Python 2
long(digit_str, 2)
或
# Python 3
int(digit_str, 2)
bitstring
库或者,正如Marc B在评论中建议的那样,使用bitstring
library。具体而言,要进行转换,请使用bitstring.pack
function。
对于霍夫曼编码,使用bitstring
可能优于将数据存储在byte
- 字符串中,因为霍夫曼码通常不是8位的倍数; bitstring
允许您操作任意长度的位串。缺点:bitstring
不属于标准库。
答案 1 :(得分:2)
一种可能的方法(使用 bitstring 库),这有点意义,但仍然包含不正确之处:
使用 bitstring 库(感谢 Mechanical snail 和 Marc B )
写入档案。
步骤:
阅读:
代码:
ss=['01010100','10010101010','010101110101010101'] #encoded message
from bitstring import BitArray,BitStream
print 'write it to file'
with open('binary.bin','wb') as f:
s=''.join(ss);
b=BitArray(bin=s)
f.write(b.tobytes())# thanks to Scott, tobytes() method is very useful
print 'read it to file'
b=BitArray(filename='binary.bin')
print b.bin
答案 2 :(得分:1)
您需要将字符串转换为数字。 int
将可选的“基数”作为参数。所以对于你的例子中的字符串,
>>> int('01010101010', 2)
682
一旦你有一个数字(不是一个字符串),想要“真正的”二进制文件是没有意义的,因为数字是相同的,你可以在任何基础上显示它。这意味着二进制100
与小数4
的数字相同,在您的程序中它们不是不同的数字。所以,一旦你将你的字符串变成一个数字,你可以摆弄它中的位。