I have a prng that i would like to port to crystal.
Testing the output of that prng ( to e.g. dieharder ) requires binary bytes ( 0x00…0xFF).
I came up with this solution.
I was wondering if this is okay for the sole purpose of converting 64bit unsigned integers into raw byte sequence.
Hi! Could you provide some code of that random generator, and show where are you needing this? Otherwise it’s not clear how we can help you or what exactly you need.
1 Like
Sure!
crprng.cr:
# based on lehmer congruential prng
# it's fast and reasonable secure
# it outputs 8 random bytes per round
def out_put(x)
STDOUT.write_bytes(x.to_u64, IO::ByteFormat::BigEndian)
end
x_state=0_u128
x_const_small=0xda942042e4dd58b5_u128
x_const_big=0x12e15e35b500f16e2e714eb2b37916a5_u128
x_seed=rand(UInt128::MIN..UInt128::MAX)
loop do
x_state^=x_seed >> (x_state % 8)
x_state&*= x_const_big
x_state&+= x_const_small << (x_state % 8)
out_put(x_state >> 64)
end
run the prng through dieharder:
crystal build --release ./crprng.cr -o ./crprng.out
./crprng.out | dieharder -g 200 -a
The out_put function needs to produce 8bit bytes
The standard output is an IO
. You can write to it directly:
STDOUT.write_bytes((x_state >> 64).to_u64, IO::ByteFormat::BigEndian)
No need for reopening any integer classes.
1 Like