rand: refactor string sampling functions to remove redundancy (#8830)

pull/8833/head
Subhomoy Haldar 2021-02-19 14:46:02 +05:30 committed by GitHub
parent 10de905376
commit 745b40c0a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 103 additions and 34 deletions

View File

@ -9,4 +9,4 @@ pub const (
max_u64_as_f64 = f64(max_u64) + 1
u31_mask = u32(0x7FFFFFFF)
u63_mask = u64(0x7FFFFFFFFFFFFFFF)
)
)

View File

@ -138,56 +138,45 @@ pub fn f64_in_range(min f64, max f64) f64 {
}
const (
chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
english_letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
hex_chars = 'abcdef0123456789'
ascii_chars = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\\^_`abcdefghijklmnopqrstuvwxyz{|}~'
)
// string_from_set returns a string of length `len` containing random characters sampled from the given `charset`
pub fn string_from_set(charset string, len int) string {
if len == 0 {
return ''
}
mut buf := unsafe { malloc(len) }
for i in 0 .. len {
unsafe {
buf[i] = charset[intn(charset.len)]
}
}
return unsafe { buf.vstring_with_len(len) }
}
// string returns a string of length `len` containing random characters in range `[a-zA-Z]`.
pub fn string(len int) string {
mut buf := unsafe {malloc(len)}
for i in 0 .. len {
unsafe {
buf[i] = rand.chars[intn(rand.chars.len)]
}
}
return unsafe { buf.vstring_with_len(len) }
return string_from_set(rand.english_letters, len)
}
const (
hex_chars = 'abcdef0123456789'
)
// hex returns a hexadecimal number of length `len` containing random characters in range `[a-f0-9]`.
pub fn hex(len int) string {
mut buf := unsafe {malloc(len)}
for i in 0 .. len {
unsafe {
buf[i] = rand.hex_chars[intn(rand.hex_chars.len)]
}
}
return unsafe { buf.vstring_with_len(len) }
return string_from_set(rand.hex_chars, len)
}
const (
ascii_chars = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\\^_`abcdefghijklmnopqrstuvwxyz{|}~'
)
// ascii returns a random string of the printable ASCII characters with length `len`.
pub fn ascii(len int) string {
mut buf := unsafe {malloc(len)}
for i in 0 .. len {
unsafe {
buf[i] = rand.ascii_chars[intn(rand.ascii_chars.len)]
}
}
return unsafe { buf.vstring_with_len(len) }
return string_from_set(rand.ascii_chars, len)
}
// uuid_v4 generates a random (v4) UUID
// See https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)
pub fn uuid_v4() string {
buflen := 36
mut buf := unsafe {malloc(37)}
mut buf := unsafe { malloc(37) }
mut i_buf := 0
mut x := u64(0)
mut d := byte(0)
@ -240,7 +229,7 @@ pub fn ulid() string {
// ulid_at_millisecond does the same as `ulid` but takes a custom Unix millisecond timestamp via `unix_time_milli`.
pub fn ulid_at_millisecond(unix_time_milli u64) string {
buflen := 26
mut buf := unsafe {malloc(27)}
mut buf := unsafe { malloc(27) }
mut t := unix_time_milli
mut i := 9
for i >= 0 {

View File

@ -188,3 +188,83 @@ fn test_rand_byte() {
assert all[0] != all[255]
assert all[0] != all[128]
}
const (
string_count = 25
)
fn test_rand_string_from_set() {
sets := [
'0123456789',
'qwertyuiop',
'abcdefghijklmnopqrstuvwxyz',
]
for charset in sets {
for _ in 0 .. string_count {
len := rand.intn(rnd_count)
str := rand.string_from_set(charset, len)
assert str.len == len
for character in str {
position := charset.index(character.ascii_str()) or { -1 }
assert position > -1
}
}
}
}
fn test_rand_string() {
rand.seed([u32(0), 1])
outputs := [
'rzJfVBJgvAyCNpEdXIteDQezg',
'AJOeswgoelDOCfcrSUWzVPjeL',
'NQfKauQqsXYXSUMFPGnXXPJIn',
'vfBGUKbpLoBMQVYXfkvRplWih',
'aYHLjMJqvUJmJJHGxEnrEmQGl',
'rBJXkQZcembAteaRFoxXmECJo',
'HYVLfHmDOCTlSbiSzHrsAIaBH',
'zgOiwyISjLSdLGhLzJsSKHVBi',
'UiAtobWXGcHsEtgzuNatxfkoI',
'NisnYlffJgFEcIdcgzWcGjnHy',
]
for output in outputs {
assert rand.string(25) == output
}
}
fn test_rand_hex() {
rand.seed([u32(0), 1])
outputs := [
'fc30e495deee09e008e15ffc3',
'4320efa837788397fb59b28f4',
'4995210abf33b6765c240ce62',
'f3d20dbe0a8aa6b9c88cd1f6f',
'8d7d58b256ab00213dd519cf7',
'fa2251284bc20a21eff48127c',
'5fef90cdc0c37143117599092',
'2a6170531c76dfb50c54126bc',
'a686dfd536042d1c1a9afdaf4',
'7f12013f6e1177e2d63726de3',
]
for output in outputs {
assert rand.hex(25) == output
}
}
fn test_rand_ascii() {
rand.seed([u32(0), 1])
outputs := [
"2Z:&PeD'V;9=mn\$C>yKg'DIr%",
'Ub7ix,}>I=&#2QJki{%FHKv&K',
'1WStRylMO|p.R~qqRtr&AOEsd',
'yka<GPZ&m+r0^Zi!ShB*1dU~W',
'uDA?.zU2X,<DkKT#_-halW\\ki',
'fsx!@uRc?re/fSPXj`Y&\\BU}p',
'fI_qM"):2;CUno!<dX:Yv*FX$',
'FnA(Fr|D`WZVWEzp<k)O;auub',
"QRkxH!kjXh&/j{)uSe&{D'v?|",
"_CyaU\$z':#}At*v2|xDu6w=;1",
]
for output in outputs {
assert rand.ascii(25) == output
}
}