Published on

Unleash the Power of UUIDs in JavaScript: From Readability to Conciseness

Authors

High readability

function generateUUID() {
  const chars = '0123456789abcdef';
  let uuid = '';

  for (let i = 0; i < 36; i++) {
    if (i === 8 || i === 13 || i === 18 || i === 23) {
      uuid += '-';
    } else if (i === 14) {
      uuid += '4';
    } else {
      const randomIndex = Math.floor(Math.random() * 16);
      uuid += chars[randomIndex];
    }
  }

  return uuid;
}
  1. The generateUUID() function initializes an empty string uuid to store the generated UUID.
  2. It defines a string chars that contains all the valid hexadecimal characters.
  3. A for loop is used to iterate 36 times, which is the length of a version 4 UUID.
  4. Inside the loop, it checks if the current index corresponds to the positions where hyphens should be inserted (index 8, 13, 18, and 23). If so, it appends a hyphen ('-') to the uuid string.
  5. At index 14, the function appends the character '4' to indicate the version of the UUID.
  6. For all other indices, a random index is generated using Math.random() and Math.floor(), and the corresponding character from the chars string is appended to the uuid string.
  7. Finally, the function returns the generated UUID.

Example usage:

const uuid = generateUUID();
console.log(uuid); // Output: e.g., 'f5b6c894-a68d-4c61-9c18-38fc48bea40e'

Concise but readable

The function uses a regular expression and the replace method to generate the UUID format.

function generateUUID() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
    var r = (Math.random() * 16) | 0,
      v = c === 'x' ? r : (r & 0x3) | 0x8
    return v.toString(16)
  })
}
  1. For each x or y character in the format, it generates a random hexadecimal digit (r) between 0 and 15.
  2. For x, it uses the random digit directly.
  3. For y, it generates a random digit (r) and sets the most significant bits to 1 and 0, respectively (r & 0x3 | 0x8).
  4. Finally, it converts the generated digits to a hexadecimal string using the toString(16) method.

Example usage:

const uuid = generateUUID()
console.log(uuid) // Output: '6c8c1593-6ed9-4f5b-9a64-70e92f3b4149'

Most concise

The code leverages the cryptographic strength of crypto.getRandomValues() to generate random values for each digit in the UUID, ensuring a relatively high level of uniqueness.

function generateUUID() {
  return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) =>
    (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16)
  )
}
  1. The function begins with an array-like expression [1e7] + -1e3 + -4e3 + -8e3 + -1e11. This is a shorthand way of creating an array with a single element, where the element itself is a sum of several negative exponents of 10.
  2. The array is then converted to a string representation using .toString().
  3. The replace() method is called on the string representation of the array with the regular expression /[018]/g. This regular expression matches any occurrence of the digits 0, 1, or 8.
  4. For each matched digit, the provided callback function (c) => ... is executed.
  5. Within the callback function, a random value is generated using crypto.getRandomValues(new Uint8Array(1)). This method is part of the Web Cryptography API and returns cryptographically strong random values. Here, it generates a single random byte.
  6. The generated random byte is then bitwise-ANDed with a bitmask (15 >> (c / 4)) to extract the relevant bits. This bitmask is created based on the current matched digit (c) divided by 4. It effectively determines the number of bits to keep from the generated random byte.
  7. The bitwise XOR operation ^ is used to toggle the bits of the currently matched digit (c) with the extracted bits from the random byte.
  8. Finally, the resulting value is converted to a hexadecimal string using .toString(16).

Example usage:

const uuid = generateUUID()
console.log(uuid) // Output: 'd50ee05a-7788-4568-9b55-d49d318467fb'

Interesting UUID resources

The previous methods are likely suitable for non-critical applications. If you’re looking for something more performant, tested, or customizable, consider using a library.

  • 🔬 Nanoid - a A tiny (130 bytes), secure, URL-friendly, unique string ID generator for JavaScript capable of producing short IDs.
  • 📐 Nanoid calculator to understand the collision probability when reducing the character length of an ID.
  • 💪 UUID - Generate RFC-compliant UUIDs in JavaScript for RFC4122 version 1, 3, 4, and 5 UUIDs