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

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

View File

@ -188,3 +188,83 @@ fn test_rand_byte() {
assert all[0] != all[255] assert all[0] != all[255]
assert all[0] != all[128] 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
}
}