将霍夫曼代码字符串转换为二进制

时间:2011-08-29 02:47:17

标签: python binary huffman-code

我遇到如何将huffman编码字符串转换为二进制python的问题。

这个问题不涉及霍夫曼算法。

就像这样:

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

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

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

我想要的是每0和1是

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

修改1:

请原谅我没有说清楚我的问题。

让我解释一下我目前写入零和一些二进制文件的方法。

说,我们可以使用代码字符串s ='010101010'。

  1. 我使用int将其转换为整数
  2. 然后使用unichr将其转换为字符串,以便我可以将其写入文件
  3. 以二进制模式将字符串写入文件
  4. 另外需要注意的是,我需要读取文件才能解码霍夫曼代码。

    所以我的方法是,

    1. 从文件中读取字节
    2. 将它们恢复为int
    3. 将int转换为其二进制表示字符串。
    4. 解码字符串
    5. 第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占用两个字节。

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

3 个答案:

答案 0 :(得分:2)

您可能希望在Python中使用两种不同的“二进制”表示形式。

Bignum的

一个是“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

写入档案。

步骤:

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

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

      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的数字相同,在您的程序中它们不是不同的数字。所以,一旦你将你的字符串变成一个数字,你可以摆弄它中的位。