rand: fix rand.uuid_v4()'s clock_seq_hi_and_reserved field
parent
c9867a9ae4
commit
3c38abc56e
|
@ -1,9 +1,11 @@
|
|||
module rand
|
||||
|
||||
import time
|
||||
|
||||
const clock_seq_hi_and_reserved_valid_values = [`8`, `9`, `a`, `b`]
|
||||
|
||||
// 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_noscan(37) }
|
||||
|
@ -31,20 +33,26 @@ pub fn uuid_v4() string {
|
|||
x = x >> 8
|
||||
d = byte(x)
|
||||
unsafe {
|
||||
buf[19] = if d > 0x39 { d + 0x27 } else { d }
|
||||
// From https://www.ietf.org/rfc/rfc4122.txt :
|
||||
// >> Set the two most significant bits (bits 6 and 7) of the clock_seq_hi_and_reserved
|
||||
// >> to zero and one, respectively.
|
||||
// all nibbles starting with 10 are: 1000, 1001, 1010, 1011 -> hex digits `8`, `9`, `a`, `b`
|
||||
// these are stored in clock_seq_hi_and_reserved_valid_values, choose one of them at random:
|
||||
buf[19] = rand.clock_seq_hi_and_reserved_valid_values[d & 0x03]
|
||||
// >> Set the four most significant bits (bits 12 through 15) of the
|
||||
// >> time_hi_and_version field to the 4-bit version number from Section 4.1.3.
|
||||
buf[14] = `4`
|
||||
buf[8] = `-`
|
||||
buf[13] = `-`
|
||||
buf[18] = `-`
|
||||
buf[23] = `-`
|
||||
buf[14] = `4`
|
||||
buf[buflen] = 0
|
||||
buf[buflen] = 0 // ensure the string will be 0 terminated, just in case
|
||||
// for i in 0..37 { println('i: ${i:2} | ${buf[i].ascii_str()} | ${buf[i].hex()} | ${buf[i]:08b}') }
|
||||
return buf.vstring_with_len(buflen)
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
ulid_encoding = '0123456789ABCDEFGHJKMNPQRSTVWXYZ'
|
||||
)
|
||||
const ulid_encoding = '0123456789ABCDEFGHJKMNPQRSTVWXYZ'
|
||||
|
||||
// ulid generates an Unique Lexicographically sortable IDentifier.
|
||||
// See https://github.com/ulid/spec .
|
||||
|
|
|
@ -12,9 +12,13 @@ fn test_rand_uuid_v4() {
|
|||
assert uuid1.len == 36
|
||||
assert uuid2.len == 36
|
||||
assert uuid3.len == 36
|
||||
assert uuid1[14] == `4`
|
||||
assert uuid2[14] == `4`
|
||||
assert uuid3[14] == `4`
|
||||
for i in 0 .. 1000 {
|
||||
x := rand.uuid_v4()
|
||||
// check the version field is always 4:
|
||||
assert x[14] == `4`
|
||||
// and the clock_seq_hi_and_reserved field is valid too:
|
||||
assert x[19] in [`8`, `9`, `a`, `b`]
|
||||
}
|
||||
}
|
||||
|
||||
// ulids:
|
||||
|
|
|
@ -3,4 +3,6 @@ import rand
|
|||
fn main() {
|
||||
n := rand.intn(1000)
|
||||
println(n)
|
||||
u := rand.uuid_v4()
|
||||
println(u)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue