logo

Learning the Basics of Coding - UUID Generation in LotusScript

Part of the Gears work I've been doing involved generating a random string to use as a "Sync ID" for a device. The server then knows where data has been taken offline to. It can then decide whether to allow it be either taken down to or sent back from a device with a different Sync ID.

This worked well and I was happy that the Sync ID format I'd come up with was suitably random. Then I happened to read Google's advice on the matter and noticed they recommend using GUIDs. This got me interested, so I read more on Wikipedia, where they say of their uniqueness:

... consider the observable universe, which contains about 5x1022 stars; every star could then have 6.8x1015 unique GUIDs.

That's the kind of geeky over-the-topness I love. Not just that it was over the top but also that they look so much more professional than some random string. Where the Sync IDs used to look something like this:

7y*e435ua^t$!q7G

Now they look like:

02D5FA82-42C1-42B7-8F9E-D188EE51F93F

Makes no difference to anybody but me really, but I like to be happy with the work I've done, no matter if other people will every appreciate the details or not.

Generating a UUID

Generating a GUID (a variant of a UUID) was easy.  I just did a quick Google and and soon found this simple bit of JavaScript. Once pasted in to my JavaScript file it worked straight away. Job done.

What niggled me was that I didn't understand what the code was doing and I don't like to just paste in any old code off the Google without really knowing what it's doing.

The logic of the code was simple -- perform a loop 36 times and build a string of random "hex" characters (0 to 9 and A to F), with a dash ("-") here and there. What had me perplexed was the following line which chose the character to insert:

uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r & 0xf];

In particular it was the single pipe (|) and single ampersand (&) that through me. Not to mention the odd-looking 0xf and stuff.

I've been coding in JavaScript for 10 years or more now and am used to using || and && in my code, but I'd never seen a pipe or a ampersand used in anything other than a pair.

After reaching for my copy of O'Reilly's JavaScript Pocket Guide, I soon found out that their singular use was as an a "bitwise operator" and after reading this Mozilla Developer Center page (a couple of times) it all started to make some kind of sense.

If like me of last week you don't just don't get it, then it's probably worth me writing a quick layman's guide.

A Quick Guide To Binary Counting

Here's a table with the numbers 1 to 9 in binary form:

Number Binary Equates To
1 0001 0+0+0+1
2 0010 0+0+2+0
3 0011 0+0+2+1
4 0100 0+4+0+0
5 0101 0+4+0+1
6 0110 0+4+2+0
7 0111 0+4+2+1
8 1000 8+0+0+0
9 1001 8+0+0+1

Given any binary string you can convert it to a real number by working from the right-most "bit" (a 1 or a 0) and working towards the left. If the first bit is a 1 then you add one (to zero at this point, so you have 1). If the bit to the left of the first bit is a 1 you add 2 (now you have 3). If the bit to the left of that bit is 1 then you add 4 (now you have 7). This carries on. Notice each time you move one bit to the left the number you add doubles.

Bitwise Operations

Doing bitwise operations simply means you put the binary form of two numbers next to each other and compare the bits in each position of each binary string. For example, let's take the bitwise operation (5 | 2). This is a "bitwise or" and means we compare the bits in each number and if either of them are a 1 then we put a 1 in the same position in the resulting binary number. Otherwise we use a 0 in that position.

Here's an example of a bitwise Or operation.

  Number Binary Operation
  5 0101 |
  2 0010  
Result 7 0111  

Now let's look at a "Bitwise And" comparison of two numbers. In this case the resulting binary only has a 1 in each position where both the binary numbers we're inspecting also have a 1.

For example:

  Number Binary Operation
  5 0101 &
  2 0010  
Result 0 0000  

So, 5 | 2 = 7 whereas 5 & 2 = 0. Hope that makes sense?

Back to the JavaScript

Let's look again at the JavaScript that had me perplexed:

uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r & 0xf];

The other thing which threw me was the hex number format. Although it looked familiar it took a while to work out that 0x3 is just another way (hex notation) of writing the number 3. Same goes for 0x8 being 8. While 0xf is 15, which is 00001111 in binary (8+4+2+1).  

With this knowledge I was ready to port the code.

Porting to LotusScript

Reproducing the logic of the ifs and for loops from JavaScript to LotusScript didn't take long. What took me some time was working out how to represent hex numbers in LotusScript. After a while I worked it out and this line of code of JavaScript:

uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r & 0xf];

Became this LotusScript:

If i=20 Then
 uuid(i) = chars( ( r And &H3 ) Or &H8 )
Else
 uuid(i) = chars( r And &HF )
End If

The LotusScript works well and you can see a demo of it in use here. If you want a copy of the code before I make a new version of DEXT available then here's a LotusScript file with it.

Happy Now?

Although I had now ported the code and felt happier that I understood what it was doing I still had no idea why it was doing it!

Even with my new-found knowledge of Bitwise operators I still didn't know why it was comparing with 3 and then 9 for the 20th character in the string. Even after a glance at the spec it made no sense. That's the point where I decided I didn't need to go to that level and stopped worrying about it. Although, if anybody can enlighten me...

Something else I didn't get was why the author of the JavaScript was doing a Bitwise And comparison with 15 (1111) as, from what I could see, any hex number less than 16 when compared with 15 is always just itself! e.g: 7 & 15 = 15.

The other part of the JavaScript I didn't get was why it did a "bitwise or" of the random number generated with 0, like so:

r = 0 | rnd()*16;

A "bitwise or" with 0 always just returns the number being compared with it. I can only guess that it acts like a Round() function and removes the decimal part, which can't exist in the resulting binary number. Anybody?

Summary

Whether you need to use GUIDs in your LotusScript or not or even if you ever need to use other random strings of any length, hopefully, like me, you'll have learnt something if you've read this far? Even if all you've learnt it that Jake doesn't know the first thing about Computer Science...

Comments

    • avatar
    • Paul van Rijswijk
    • Tue 14 Jul 2009 06:09 AM

    by doing a 0 | rnd() * 16 you 'convert' the float number to integer

    • avatar
    • Paul van Rijswijk
    • Tue 14 Jul 2009 06:20 AM

    It has to do with the way floating points are kept in 32 bits

    http://en.wikipedia.org/wiki/Single_precision

    • avatar
    • Jake Howlett
    • Tue 14 Jul 2009 09:30 AM

    Thanks Paul. That's what I assumed it was doing, but it's good to have it confirmed. I'll read the link you posted later on tonight and see if I can get my head round it. I would like to get to know more about the pure science of computing...

    • avatar
    • Aaron Hardin
    • Tue 14 Jul 2009 02:42 PM

    Thanks, interesting reading. I want to try it, currently I do things differently.

    Sorry I can't add any value. ;)

    • avatar
    • Neil
    • Wed 15 Jul 2009 08:40 AM

    Is the NotesDocument.UniversalID a valid UUID. If so, could you reuse it from the related NotesDocuments with some added dashes?

  1. Great article, Jake!

    I'll do an article for ESLUG (http://www.slug.es/ ) in Spanish with parts of your article. When it' will finished i'll tell you.

    Regards!

    • avatar
    • broofa
    • Wed 14 Oct 2009 04:35 PM

    Hi Jake, As the author of the UUID javascript code in question let me try to answer some of your questions ...

    "I still didn't know why it was comparing with 3 and then 9 for the 20th character in the string"

    I think you meant "and then 8", right? The reason for this is an obscure clause in the UUID spec (RFC 4122). It's in section 4.4., and says, "Set the two most significant bits (bits 6 and 7) of the clock_seq_hi_and_reserved to zero and one, respectively." The why and wherefor of this isn't worth going into, but what this means is that the hex digit at i=19 has to be of the binary form, "10XX", where the X's are randomly set bits. If you work through it, I think you'll see that "(r & 0x3) | 0x8" accomplishes just that.

    "Something else I didn't get was why the author of the JavaScript was doing a Bitwise And comparison with 15 (1111) as, from what I could see, any hex number less than 16 when compared with 15 is always just itself! e.g: 7 & 15 = 15."

    ... and ...

    "The other part of the JavaScript I didn't get was why it did a 'bitwise or' of the random number generated with 0"

    In both these cases, I'm taking advantage of a behavior of bitwise operators in JavaScript: When applying a bitwise operation to a float value, that value is first converted to an integer. Thus, "0 | r" is a slightly terser and faster wa of doing "Math.floor(r)". The same is true for "r & 0xf" when 'r' < 16.

    (Speaking of which, yeah, the "r & 0xf" could just be "r" since 'r' has already been converted to an int on the prior line, by doing "0 | ...".

    Anyhow, hope this helps clear things up. Feel free to drop a comment on my broofa.com UUID page if you have other questions.

    • avatar
    • Jake Howlett
    • Thu 15 Oct 2009 03:46 AM

    Thanks Broofa. Still a bit over my head, but thanks for the clarification. At least I got some bits right.

Your Comments

Name:
E-mail:
(optional)
Website:
(optional)
Comment:


About This Page

Written by Jake Howlett on Tue 14 Jul 2009

Share This Page

# ( ) '

Comments

The most recent comments added:

Skip to the comments or add your own.

You can subscribe to an individual RSS feed of comments on this entry.

Let's Get Social


About This Website

CodeStore is all about web development. Concentrating on Lotus Domino, ASP.NET, Flex, SharePoint and all things internet.

Your host is Jake Howlett who runs his own web development company called Rockall Design and is always on the lookout for new and interesting work to do.

You can find me on Twitter and on Linked In.

Read more about this site »

More Content