1

我在如何将霍夫曼编码字符串转换为二进制 python 时遇到问题。

这个问题与霍夫曼算法无关。

它是这样的:

我可以得到一个编码的霍夫曼字符串,比如说01010101010注意,它是一个字符串。

但现在我想将字符串表示形式保存为真正的二进制文件。

在霍夫曼编码的字符串中,每个 0 和 1 都是一个byte

我想要的是每 0 和 1有点

我怎么能在python中做到这一点?

编辑1:

请原谅我没有足够清楚地描述我的问题。

让我解释一下我目前将零写入二进制的方法。

比如说,我们可以编码字符串 s='010101010'。

  1. int用来将其转换为整数
  2. 然后用于unichr将其转换为字符串,以便我可以将其写入文件
  3. 以二进制模式将字符串写入文件

还要注意的是,我需要读取文件才能解码霍夫曼代码。

所以我的方法是,

  1. 从文件中读取字节
  2. 将它们恢复为 int
  3. 将 int 转换为其二进制表示字符串。
  4. 解码字符串

第 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占用了两个字节。

那么,当我从文件中读取这些字节时,我应该一次读取多少字节?

4

3 回答 3

2

您可能想要使用 Python 中的两种不同的“二进制”表示。

比格南

一种是“bignum”或任意精度整数。这种类型long在 Python 2.x 和intPython 3.x 中被调用。顾名思义,这种表示在语义上是一个任意长度的整数,因此如果您打算对结果数字进行算术运算,它会很有用。要解析一串二进制数字,请使用

# Python 2
long(digit_str, 2)

或者

# Python 3
int(digit_str, 2)

bitstring图书馆

或者,正如 Marc B 在评论中建议的那样,使用bitstringlibrary。具体来说,对于转换,使用bitstring.pack函数.

对于霍夫曼编码,使用bitstring可能比在 -string 中存储数据更可取byte,因为霍夫曼编码通常不是 8 位的倍数;bitstring允许您操作任意长度的位串。缺点:bitstring不是标准库的一部分。

于 2011-08-29T03:47:52.843 回答
2

一种可能的方法(使用位串库)有一定意义,但仍然包含不正确之处:

使用位串库(感谢Mechanical snailMarc B

用于写入文件。

脚步:

  1. 将纯文本编码为二进制表示字符串
  2. 连接所有这些字符串以形成一个更长的字符串
  3. 使用bitstring.BitArray转换为十六进制格式
  4. 将十六进制字符串写入文件

阅读:

  1. 从文件中读取十六进制字符串
  2. 使用BitArray将其转换回位串
  3. 开始解码

代码:

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
于 2011-08-29T12:31:16.223 回答
1

您有一个字符串,需要将其转换为数字。int将可选的“base”作为参数。因此,对于您示例中的字符串,

>>> int('01010101010', 2)
682

一旦你有了一个数字(不是字符串),想要“真正的”二进制是没有意义的,因为数字是相同的,你可以在任何基础上显示它。这意味着二进制100与十进制数字相同4,在您的程序中它们不是不同的数字。所以,一旦你把你的字符串变成一个数字,你就可以摆弄它里面的位。

于 2011-08-29T03:02:41.383 回答