rand: add `pub fn rand.read(mut buf []byte)` and `pub fn rand.bytes(needed int) ?[]byte{}` + tests
parent
ece73836aa
commit
66f21cae55
|
@ -138,3 +138,17 @@ fn init() {
|
||||||
default_rng = new_default()
|
default_rng = new_default()
|
||||||
C.atexit(deinit)
|
C.atexit(deinit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// read fills in `buf` a maximum of `buf.len` random bytes
|
||||||
|
pub fn read(mut buf []byte) {
|
||||||
|
p64 := unsafe { &u64(buf.data) }
|
||||||
|
u64s := buf.len / 8
|
||||||
|
for i in 0 .. u64s {
|
||||||
|
unsafe {
|
||||||
|
*(p64 + i) = default_rng.u64()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i in u64s * 8 .. buf.len {
|
||||||
|
buf[i] = byte(default_rng.u32())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -65,3 +65,10 @@ pub fn ulid_at_millisecond(unix_time_milli u64) string {
|
||||||
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// read fills in `buf` a maximum of `buf.len` random bytes
|
||||||
|
pub fn read(mut buf []byte) {
|
||||||
|
for i in 0 .. buf.len {
|
||||||
|
buf[i] = byte(default_rng.u32())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -174,6 +174,16 @@ pub fn f64_in_range(min f64, max f64) f64 {
|
||||||
return default_rng.f64_in_range(min, max)
|
return default_rng.f64_in_range(min, max)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bytes returns a buffer of `bytes_needed` random bytes
|
||||||
|
pub fn bytes(bytes_needed int) ?[]byte {
|
||||||
|
if bytes_needed < 0 {
|
||||||
|
return error('can not read < 0 random bytes')
|
||||||
|
}
|
||||||
|
mut res := []byte{len: bytes_needed}
|
||||||
|
read(mut res)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
english_letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
english_letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||||
hex_chars = 'abcdef0123456789'
|
hex_chars = 'abcdef0123456789'
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
import rand
|
||||||
|
|
||||||
|
fn test_rand_bytes() ? {
|
||||||
|
mut randoms := []string{}
|
||||||
|
for i in 0 .. 100 {
|
||||||
|
x := rand.bytes(i) ?.hex()
|
||||||
|
if x.len > 0 {
|
||||||
|
randoms << x
|
||||||
|
}
|
||||||
|
assert x.len == i * 2
|
||||||
|
}
|
||||||
|
mut differences := 0
|
||||||
|
for idx in 1 .. randoms.len {
|
||||||
|
start := randoms[idx]#[0..8]
|
||||||
|
prev_start := randoms[idx - 1]#[0..8]
|
||||||
|
if start != prev_start {
|
||||||
|
differences++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert differences > 95 // normally around 98
|
||||||
|
dump(differences)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_rand_read() ? {
|
||||||
|
max := 50
|
||||||
|
mut a := []byte{len: max}
|
||||||
|
mut differences := 0
|
||||||
|
for j in 1 .. max {
|
||||||
|
start := '00'.repeat(j)
|
||||||
|
for k in j + 1 .. max {
|
||||||
|
end := '00'.repeat(max - k)
|
||||||
|
middle := '00'.repeat(k - j)
|
||||||
|
// eprintln('> j: $j | k: $k | start: $start | middle: $middle | end: $end')
|
||||||
|
for i in 0 .. max {
|
||||||
|
a[i] = 0
|
||||||
|
}
|
||||||
|
assert a[j..k].hex() == middle
|
||||||
|
for i in 0 .. 10 {
|
||||||
|
rand.read(mut a[j..k])
|
||||||
|
// dump(a.hex())
|
||||||
|
assert a[0..j].hex() == start
|
||||||
|
assert a[k..].hex() == end
|
||||||
|
if a[j..k].hex() != middle {
|
||||||
|
differences++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dump(differences)
|
||||||
|
assert differences > 11700 // normally around 11758
|
||||||
|
}
|
Loading…
Reference in New Issue