Sitemap

Bit masking operations for UUIDs

2 min readOct 16, 2026

--

Press enter or click to view image in full size
Photo by Rich Smith on Unsplash

There are eight officially recognized versions of universally unique identifiers (UUIDs), and three officially recognized variants. The neat thing here is that information about versions and variants is embedded right into the UUIDs.

All it takes for your program to recognize the different versions and variants is to perform some simple bit masking and bit shifting operations. The human-readable forms of UUIDs are designed so that the hexadecimal digits identifying the version and the variant each occur after a dash.

UUIDs are essentially unsigned 128-bit integers. But most computers today use 64-bit processors, so it’s generally necessary to split UUIDs into two pairs of 64-bit integers. That’s what happens in the Java Development Kit: the java.util.UUID constructor takes two integers of type long.

The human-readable form of an UUID consists of 32 hexadecimal digits separated by dashes in the pattern 8–4–4–4–12. For example, 01234567-89AB-CDEF-0123–456789ABCDEF. Because of the way Medium formats these articles, you might have to convert some dashes to ASCII dashes before you put the examples in this article through various tools.

The first hexadecimal digit in the second group of four gives the version, and the first hexadecimal digit in the third group of four gives the variant. In the example above, the version is 12 (hexadecimal digit C), which has not been assigned yet, and the variant is 0, Apollo Network Computing Systems (NCS) backward compatible.

Get Alonso Del Arte’s stories in your inbox

Join Medium for free to get updates from this writer.

Here are a few examples of UUIDs that are more like those you might encounter “in the wild.”

  • 2E60B0C9–0B7A-7D44–95C8-E8BA1CF92163
  • 594EFF85-C398-4CF1-A9B0-CA3B489A1F4F
  • 9E2CFDBB-0CB6-4482-C039–54DC1F984CF8
  • EB532D6A-D311–74D7–94D1–1F4CAA5058E6

These UUIDs don’t correspond to anything that I am aware of. Collisions are theoretically possible but practically impossible.

The version bits are fairly low in the higher 64 bits. A bitwise AND with 61440 applied to the four examples above will give either 16384 or 28672. Then shift that twelve bits to the right to get either 4 or 7 in these examples. It doesn’t matter if the shift is signed or unsigned because the bitwise AND should have eliminated any negative sign extension.

The variant bits, on the other hand, sit very high up in the lower 64 bits. Use bitwise AND −1152921504606846976 to mask out the four high bits of the lower 64 bits, then do an unsigned right shift to move those four high bits 60 bits to right. In the four examples above, we’d thus get 9, 10 or 12. A signed right shift would give −7, −6 or −4.

--

--

Alonso Del Arte
Alonso Del Arte

Written by Alonso Del Arte

is a Java and Scala developer from Detroit, Michigan. AWS Cloud Practitioner Foundational certified