Shankar
Shankar

Reputation: 117

How to create a version 3 or version 5 UUID implementation in javascript?

Is there a library available that does that? I referred to this answer but it only has other versions not version 3 or 5.

Create GUID / UUID in JavaScript?

Upvotes: 0

Views: 370

Answers (2)

Lee Jisol
Lee Jisol

Reputation: 37

The Web Crypto API allows you to generate UUID version 5 in your browser (version 3 cannot be generated because MD5 is not supported).

/**
 * @copyright (c) 2024 Lee Jisol
 * @license 0BSD
 */

/**
 * @param {Uint8Array} namespace
 * @param {Uint8Array} name
 * @returns {Promise<string>}
 */
async function namedUUID(namespace, name) {
  const len = namespace.byteLength;
  const arr = new Uint8Array(len + name.byteLength);
  arr.set(namespace);
  arr.set(name, len);

  const dig = new Uint8Array(await crypto.subtle.digest('SHA-1', arr), 0, 16);
  dig[6] = dig[6] & 0x0f | 0x50;
  dig[8] = dig[8] & 0x3f | 0x80;

  let hex = '';
  for (let i = 0; i < 16; ++i) {
    const num = dig[i];
    hex += (num < 16) ? ('0' + num.toString(16)) : num.toString(16);
  }

  return hex.slice(0, 8) + '-' +
    hex.slice(8, 12) + '-' +
    hex.slice(12, 16) + '-' +
    hex.slice(16, 20) + '-' +
    hex.slice(20, 32);
}

/** Fully-qualified domain name */
const NAMESPACE_DNS = Uint8Array.of(
  0x6b, 0xa7, 0xb8, 0x10,
  0x9d, 0xad,
  0x11, 0xd1,
  0x80, 0xb4,
  0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8
);

/** URL */
const NAMESPACE_URL = Uint8Array.of(
  0x6b, 0xa7, 0xb8, 0x11,
  0x9d, 0xad,
  0x11, 0xd1,
  0x80, 0xb4,
  0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8
);

/** ISO OID */
const NAMESPACE_OID = Uint8Array.of(
  0x6b, 0xa7, 0xb8, 0x12,
  0x9d, 0xad,
  0x11, 0xd1,
  0x80, 0xb4,
  0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8
);

/** X.500 DN (in DER or a text output format) */
const NAMESPACE_X500 = Uint8Array.of(
  0x6b, 0xa7, 0xb8, 0x14,
  0x9d, 0xad,
  0x11, 0xd1,
  0x80, 0xb4,
  0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8
);

// Example
(async() => {
  const dns = 'www.example.com';
  const url = 'http://www.example.com/';
  const enc = new TextEncoder();
  const [dnsId, urlId] = await Promise.all([
    namedUUID(NAMESPACE_DNS, enc.encode(dns)),
    namedUUID(NAMESPACE_URL, enc.encode(url)),
  ]);
  console.log(dnsId); // "2ed6657d-e927-568b-95e1-2665a8aea6a2"
  console.log(urlId); // "fcde3c85-2270-590f-9e7c-ee003d65e0e2"
})();

(This code is from my gist.)

Upvotes: 0

Bogdan M.
Bogdan M.

Reputation: 2181

A useful uuid implementation in JS is the package:

https://www.npmjs.com/package/uuid

why?
weekly downloads
13,478,626

also: Support for version 1, 3, 4 and 5 UUIDs

In the future, you could search NPM yourself and take as a reliable metric the weekly downloads.

Upvotes: 2

Related Questions