有效地将字节打包成整数?

时间:2014-09-15 18:17:17

标签: haskell

这是一开始看似简单的问题之一,但我现在已经研究了一段时间而无法找到答案......

我需要将字节列表(ie- Word8 s)转换为任意长度的数字(即Integer)。例如

intPack::[Word8]->Integer
intPack [1] = 1
intPack [1, 0] = 256
showHex (intPack [1,2,3,4,5,6,7,8,9,10,11]) "" = "102030405060708090a0b"

缓慢的解决方案很容易编写(参见How to convert a ByteString to an Int and dealing with endianness?

中的答案
intPack = foldl (\v -> ((v*256) +)) 0

....但是我对此感到畏缩,所有额外的乘法和加法,加上在中间创建的一串无用的整数,只是为了(可能)得到我开始填充到内部结构中的相同字节整数类型。

当然,我不知道Integer如何存储数据的细节(也许它比在可变长度数组中保存字节更复杂......就像使用flags来表示它的长度一样数字,就像utf-8编码字符时那样。至少知道上面的intPack和它一样好是很好....然后我可以停止我的研究,咬(或者更确切地说:) :)子弹,继续前进。

1 个答案:

答案 0 :(得分:3)

我会查看binary包,以便有效地打包和解包二进制数据结构:

https://hackage.haskell.org/package/binary-0.7.2.1/docs/Data-Binary-Get.html

一些想法:

  1. 查看Binary Integer实例是否适合您:

    import Data.Binary
    import qualified Data.ByteString.Lazy.Char8 as LBS
    main = do
      let i = 0x0102030405060708090a0b0c0d0e0f :: Integer
          bs = encode i
      print ("before", i)
      LBS.writeFile "output" bs
      j <- fmap decode $ LBS.readFile "output" :: IO Integer
      print ("after", j)
    
  2. 查看word64be等函数的定义,看看它是否为您提供了任何想法:

  3. http://hackage.haskell.org/package/binary-0.7.2.1/docs/src/Data-Binary-Get.html#getWord64be