Custom PRNG binary output

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