A Version 4 UUID Implementation I've been toying around with writing a decentralized, P2P application in REBOL 2, and one of the things I need to do is generate a universally unique identifier for users. I have written a function that generates a Version 4 UUID that is compliant with RFC 4122, as best as I can tell.

I have a few questions ...


Is it compliant with RFC 4122? Have I missed anything?
I am fairly new to REBOL. Is there a simpler approach I could have taken with the code? Am I using best practices in the language?
The code picks random integers and does some bitwise operations using integers too. Is it correct to do things this way? All the online examples I've come across use bytes directly and does the bitwise operations using hexidecimal numbers. REBOL doesn't support bytes directly and so that's why I've coded things this way. It appears to work correctly, but I have this nagging feeling that maybe I've overlooked something at a lower level.


Here is the REBOL 2 code



REBOL []

; IMPORTANT - random/seed now/precise must be called before running this function
; Also, it must only be seeded ONCE per application process or duplicates will occur
makeUUID: func [
    "Generates a Version 4 UUID that is compliant with RFC 4122"
    /local data
][
    ; generate 16 random integers

    ; Note: REBOL doesn't support bytes directly 
    ; and so instead we pick numbers within the
    ; unsigned, 8-bit, byte range (0 - 255)

    ; Also random normally begins the range at 1, 
    ; not 0, and so -1/256 allows 0 to be picked
    data: collect [loop 16 [keep -1 + random/secure 256]]

    ; set the first character in the 7th "byte" to always be 4
    data/7: data/7 and 15 or 64

    ; set the first character in the 9th "byte" to always be 8, 9, A or B
    data/9: data/9 and 63 or 128

    ; convert the integers to hexadecimal
    data: enbase/base to binary! data 16

    ; add the hyphens between each block 
    data: insert skip data 8 "-"
    data: insert skip data 4 "-"
    data: insert skip data 4 "-"
    data: insert skip data 4 "-"

    head data
]

random/seed now/precise
for num 1 30 1 [print makeUUID]
halt
this isn't much shorter but instead of 

; add the hyphens between each block 
data: insert skip data 8 "-"
data: insert skip data 4 "-"
data: insert skip data 4 "-"
data: insert skip data 4 "-"

head data


you could write

parse data [8 skip insert "-" 3 [5 skip insert "-"] to end]
data


And you don't need a for loop

loop 30 [print makeuuid]