2023-11-01 03:32:09 +00:00
|
|
|
# Nimbus
|
|
|
|
# Copyright (c) 2020-2023 Status Research & Development GmbH
|
|
|
|
# Licensed under either of
|
|
|
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
|
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0)
|
|
|
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or
|
|
|
|
# http://opensource.org/licenses/MIT)
|
|
|
|
# at your option. This file may not be copied, modified, or distributed except
|
|
|
|
# according to those terms.
|
|
|
|
|
2020-04-29 09:22:39 +00:00
|
|
|
import random, sets, nimcrypto/sysrand
|
2020-04-22 11:04:19 +00:00
|
|
|
|
|
|
|
type
|
|
|
|
RandGen*[T] = object
|
|
|
|
minVal, maxVal: T
|
|
|
|
|
|
|
|
Bytes* = seq[byte]
|
|
|
|
|
|
|
|
proc rng*[T](minVal, maxVal: T): RandGen[T] =
|
|
|
|
doAssert(minVal <= maxVal)
|
|
|
|
result.minVal = minVal
|
|
|
|
result.maxVal = maxVal
|
|
|
|
|
|
|
|
proc rng*[T](minMax: T): RandGen[T] =
|
|
|
|
rng(minMax, minMax)
|
|
|
|
|
|
|
|
proc getVal*[T](x: RandGen[T]): T =
|
|
|
|
if x.minVal == x.maxVal: return x.minVal
|
|
|
|
rand(x.minVal..x.maxVal)
|
|
|
|
|
|
|
|
proc randString*(len: int): string =
|
|
|
|
result = newString(len)
|
|
|
|
discard randomBytes(result[0].addr, len)
|
2020-04-29 09:22:39 +00:00
|
|
|
|
2020-04-22 11:04:19 +00:00
|
|
|
proc randBytes*(len: int): Bytes =
|
|
|
|
result = newSeq[byte](len)
|
|
|
|
discard randomBytes(result[0].addr, len)
|
2020-04-29 09:22:39 +00:00
|
|
|
|
2020-04-22 11:04:19 +00:00
|
|
|
proc randPrimitives*[T](val: int): T =
|
|
|
|
type
|
|
|
|
ByteLike = uint8 | byte | char
|
|
|
|
|
|
|
|
when T is string:
|
|
|
|
randString(val)
|
|
|
|
elif T is int:
|
|
|
|
result = val
|
|
|
|
elif T is ByteLike:
|
|
|
|
result = T(val)
|
|
|
|
elif T is Bytes:
|
|
|
|
result = randBytes(val)
|
|
|
|
|
|
|
|
proc randList*(T: typedesc, fillGen: RandGen, listLen: int, unique: static[bool] = true): seq[T] =
|
|
|
|
result = newSeqOfCap[T](listLen)
|
|
|
|
when unique:
|
|
|
|
var set = initHashSet[T]()
|
|
|
|
for len in 0..<listLen:
|
|
|
|
while true:
|
|
|
|
let x = randPrimitives[T](fillGen.getVal())
|
|
|
|
if x notin set:
|
|
|
|
result.add x
|
|
|
|
set.incl x
|
|
|
|
break
|
|
|
|
else:
|
|
|
|
for len in 0..<listLen:
|
|
|
|
let x = randPrimitives[T](fillGen.getVal())
|
|
|
|
result.add x
|
|
|
|
|
|
|
|
proc randList*(T: typedesc, fillGen, listGen: RandGen, unique: static[bool] = true): seq[T] =
|
|
|
|
randList(T, fillGen, listGen.getVal(), unique)
|