rand: fix rand.uuid_v4()'s clock_seq_hi_and_reserved field
parent
c9867a9ae4
commit
3c38abc56e
|
@ -1,9 +1,11 @@
|
||||||
module rand
|
module rand
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
const clock_seq_hi_and_reserved_valid_values = [`8`, `9`, `a`, `b`]
|
||||||
|
|
||||||
// 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_noscan(37) }
|
mut buf := unsafe { malloc_noscan(37) }
|
||||||
|
@ -31,20 +33,26 @@ pub fn uuid_v4() string {
|
||||||
x = x >> 8
|
x = x >> 8
|
||||||
d = byte(x)
|
d = byte(x)
|
||||||
unsafe {
|
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[8] = `-`
|
||||||
buf[13] = `-`
|
buf[13] = `-`
|
||||||
buf[18] = `-`
|
buf[18] = `-`
|
||||||
buf[23] = `-`
|
buf[23] = `-`
|
||||||
buf[14] = `4`
|
buf[buflen] = 0 // ensure the string will be 0 terminated, just in case
|
||||||
buf[buflen] = 0
|
// 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)
|
return buf.vstring_with_len(buflen)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const ulid_encoding = '0123456789ABCDEFGHJKMNPQRSTVWXYZ'
|
||||||
ulid_encoding = '0123456789ABCDEFGHJKMNPQRSTVWXYZ'
|
|
||||||
)
|
|
||||||
|
|
||||||
// ulid generates an Unique Lexicographically sortable IDentifier.
|
// ulid generates an Unique Lexicographically sortable IDentifier.
|
||||||
// See https://github.com/ulid/spec .
|
// See https://github.com/ulid/spec .
|
||||||
|
|
|
@ -12,9 +12,13 @@ fn test_rand_uuid_v4() {
|
||||||
assert uuid1.len == 36
|
assert uuid1.len == 36
|
||||||
assert uuid2.len == 36
|
assert uuid2.len == 36
|
||||||
assert uuid3.len == 36
|
assert uuid3.len == 36
|
||||||
assert uuid1[14] == `4`
|
for i in 0 .. 1000 {
|
||||||
assert uuid2[14] == `4`
|
x := rand.uuid_v4()
|
||||||
assert uuid3[14] == `4`
|
// 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:
|
// ulids:
|
||||||
|
|
|
@ -3,4 +3,6 @@ import rand
|
||||||
fn main() {
|
fn main() {
|
||||||
n := rand.intn(1000)
|
n := rand.intn(1000)
|
||||||
println(n)
|
println(n)
|
||||||
|
u := rand.uuid_v4()
|
||||||
|
println(u)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue