我正在尝试编写一个用于加密安全随机数的Haskell库.代码如下:
module URandom (URandom, initialize) where
import qualified Data.ByteString.Lazy as B
import System.Random
import Data.Word
newtype URandom = URandom [Word8]
instance RandomGen URandom where
next (URandom (x : xs)) = (fromIntegral x, URandom xs)
split (URandom l) = (URandom (evens l), URandom (odds l))
where evens (x : _ : xs) = x : evens xs
odds (_ : x : xs) = x : odds xs
genRange _ = (fromIntegral (minBound :: Word8), fromIntegral (maxBound :: Word8))
initialize :: IO URandom
initialize = URandom . B.unpack <$> B.readFile "/dev/urandom"
Run Code Online (Sandbox Code Playgroud)
不幸的是,它并不像我想要的那样.特别是表演
take 10 . randoms <$> initialize
Run Code Online (Sandbox Code Playgroud)
产量(类似于)
[-4611651379516519433,-4611644973572935887,-31514321567846,9223361179177989878,-4611732094835278236,9223327886739677537,4611709625714976418,37194416358963,4611669560113361421,-4611645373004878170,-9223329383535098640,4611675323959360258,-27021785867556,9223330964083681227,4611705212636167666]
Run Code Online (Sandbox Code Playgroud)
对我而言,未经训练的,未经训练的眼睛,看起来并不是很随机.很多46 ......和92 ......在那里.
怎么可能出错?为什么这不能产生分布均匀的数字?值得注意的是,即使我将Word8s 连接在一起形成Ints,分布也没有改善,我认为这里的代码不值得包含.
编辑:这里有一些证据没有正确分发.我写了一个名为histogram的函数:
histogram :: ? t . (Integral t, Bounded t)
=> [t] -> Int -> S.Seq Int
histogram [] buckets = S.replicate buckets 0
histogram (x : xs) buckets = S.adjust (+ 1) (whichBucket x) (histogram xs buckets)
where whichBucket x = fromIntegral $ ((fromIntegral x * fromIntegral buckets) :: Integer) `div` fromIntegral (maxBound :: t)
Run Code Online (Sandbox Code Playgroud)
当我跑
g <- initialize
histogram (take 1000000 $ randoms g :: [Word64]) 16
Run Code Online (Sandbox Code Playgroud)
我回来了
fromList [128510,0,0,121294,129020,0,0,122090,127873,0,0,120919,128637,0,0,121657]
Run Code Online (Sandbox Code Playgroud)
有些水桶是空的!
| 归档时间: |
|
| 查看次数: |
126 次 |
| 最近记录: |