【问题标题】:How can I convert from a ByteString to a positive Integer如何从 ByteString 转换为正整数
【发布时间】:2017-11-01 07:20:58
【问题描述】:

我正在尝试生成大的随机素数(1024 位),所以我需要一种方法来生成大的正随机数。

我从System.Random 开始,但想从crypto-api 包转移到Crypto.Random。

Crypto.Random 只产生字节串,所以我需要一种转换为Integer 类型的方法。最好的方法是什么?

【问题讨论】:

  • 不是完全重复,但你看到stackoverflow.com/questions/2283119/…了吗?
  • @Thomas,我看到了,它正在向另一个方向转换,我在使用 Data.Binary 时遇到了一些麻烦。我可以轻松地将Integer 类型转换为字节串,但通常从随机字节串转换为Integer 类型会导致错误。我不知道Integer 的内部表示,但我认为生成随机字节会产生无效数字。
  • @user668074 Binary instance for Integer 写一个标签,判断它是适合几个字节的小整数还是适合多个字节的大整数,对于大整数,写一个符号字节和一个列表以长度开头的字节数;如果长度与字节数不匹配,则会出现错误。
  • @Cirdec,谢谢,我不确定整数是如何表示的。你知道 Natural 整数类型是如何表示的吗?
  • Binary instance for Natural 在同一个文件中。这些都不是它们在内存中的表示方式。两者最终都读取一个字节列表并一次折叠一个字节。与其将字节字符串格式化为这些格式之一,不如自己折叠它,如my answer所示。

标签: haskell bytestring


【解决方案1】:

无需在GHC.Integer 的内部四处寻找,您就可以将字节串折叠成Integer,一次一个字节。

import qualified Data.ByteString as BS
import Data.Bits

fromBytes :: ByteString -> Integer
fromBytes = BS.foldl' f 0
  where
    f a b = a `shiftL` 8 .|. fromIntegral b

如果您想读取Natural 数字而不是Integers,您可以给它一个更通用的类型签名。

-- Read bytes in big-endian order (most significant byte first)
-- Little-endian order is fromBytes . BS.reverse
fromBytes :: (Bits a, Num a) => ByteString -> a
fromBytes = BS.foldl' f 0
  where
    f a b = a `shiftL` 8 .|. fromIntegral b

【讨论】:

  • 一般来说,这似乎是最好的方法。我还找到了monadcryptorandom 包。它允许完全绕过Crypto.Random 模块的字节串部分并获取整数。
猜你喜欢
  • 2017-02-07
  • 1970-01-01
  • 2015-08-10
  • 1970-01-01
  • 2014-11-13
  • 2016-07-18
  • 1970-01-01
  • 1970-01-01
  • 2016-07-31
相关资源
最近更新 更多