这是一开始看似简单的问题之一,但我现在已经研究了一段时间而无法找到答案......
我需要将字节列表(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
和它一样好是很好....然后我可以停止我的研究,咬(或者更确切地说:) :)子弹,继续前进。
答案 0 :(得分:3)
我会查看binary
包,以便有效地打包和解包二进制数据结构:
https://hackage.haskell.org/package/binary-0.7.2.1/docs/Data-Binary-Get.html
一些想法:
查看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)
查看word64be
等函数的定义,看看它是否为您提供了任何想法:
http://hackage.haskell.org/package/binary-0.7.2.1/docs/src/Data-Binary-Get.html#getWord64be