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. Questions about how to generate a UUID came up on the old mailing list a few times, but no one ever had a solution. So I thought I'd share my implementation with you guys, in case anyone needs something similar. Feel free to pick it apart too. I'm fairly new to REBOL, and there might be a better approach to what I've done. Cheers!
R E B O L []
; IMPORTANT - random/seed now/precise must be called before running this function
; Also, it must only be called ONCE per application process or duplicates will occur
makeUUID: func [
'Generates a Version 4 UUID that is compliant with RFC 4122'
][
data: copy []
; 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 allows 0 to be picked
loop 16 [append data -1 + random/secure 255]
; get the 'byte' in position 7
pos7: do [pick data 7]
; get the 'byte' in position 9
pos9: do [pick data 9]
; set the first character in the 7th 'byte' to always be 4
poke data 7 do [64 or do [pos7 and 15]]
; set the first character in the 9th 'byte' to always be 8, 9, A or B
poke data 9 do [128 or do [pos9 and 63]]
; convert the integers to hexadecimal
repeat n 16 [
poke data n do [
; remove the padded 0s that REBOL adds, i.e. 0000002A = 2A
copy/part skip do [to-string to-hex pick data n] 6 2
]
]
uuid: join '' [
join '' do [copy/part skip data 0 4] '-'
join '' do [copy/part skip data 4 2] '-'
join '' do [copy/part skip data 6 2] '-'
join '' do [copy/part skip data 8 2] '-'
join '' do [copy/part skip data 10 6]
]
]
random/seed now/precise
for num 1 30 1 [print makeUUID]
halt