Подтвердить что ты не робот

Функция Hancell `randoms` не очень хорошо работает с моей библиотекой

Я пытаюсь написать библиотеку 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"

К сожалению, он не ведет себя так, как я хочу. В частности, выполнение

take 10 . randoms <$> initialize

дает (что-то похожее)

[-4611651379516519433,-4611644973572935887,-31514321567846,9223361179177989878,-4611732094835278236,9223327886739677537,4611709625714976418,37194416358963,4611669560113361421,-4611645373004878170,-9223329383535098640,4611675323959360258,-27021785867556,9223330964083681227,4611705212636167666]

который для моего, albiet неподготовленного глаза не кажется очень случайным. Много 46... и 92... там.

Что может быть не так? Почему это не приводит к хорошо распределенным цифрам? Стоит отметить, что даже если я объединил Word8 с формой Int, распределение не улучшилось, я не думал, что здесь стоит включить этот код.

Изменить: вот некоторые доказательства, которые не были распределены правильно. Я написал функцию, называемую гистограммой:

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)

и когда я запустил

g <- initialize
histogram (take 1000000 $ randoms g :: [Word64]) 16

Я возвращаюсь

fromList [128510,0,0,121294,129020,0,0,122090,127873,0,0,120919,128637,0,0,121657]

Некоторые ведра полностью пусты!

4b9b3361

Ответ 1

Проблема связана с ошибкой в ​​ random-1.0.1.1, которая была исправлена ​​в random-1.1. Список изменений указывает на этот билет. В частности, ссылаясь на более старую версию:

Также предполагается, что все реализации RandomGen производят тот же диапазон случайных значений, что и StdGen.

Здесь случайность генерируется по 8 бит за раз, что и вызвало наблюдаемое поведение.

random-1.1 исправлено:

Эта реализация также работает с любым RandomGen, даже с теми, которые производят всего лишь один бит энтропии за следующий вызов или имеют минимальную границу, отличную от нуля.