Skip to content
This repository has been archived by the owner on Feb 16, 2023. It is now read-only.

feat: describe UUID v4 algorithm #6

Merged
merged 12 commits into from
Feb 4, 2021
Merged

feat: describe UUID v4 algorithm #6

merged 12 commits into from
Feb 4, 2021

Conversation

bcoe
Copy link
Collaborator

@bcoe bcoe commented Jan 24, 2021

An initial pass at describing the UUID v4 algorithm.

Fixes #5


My goal here was to get us started, @broofa @ctavan, you know the space much better than me so please correct any strange decisions I've made.

CC: @domenic if you have the time, your feedback is greatly appreciated around the spec text.


Preview | Diff

@bcoe bcoe requested review from broofa and ctavan January 24, 2021 03:19
@bcoe
Copy link
Collaborator Author

bcoe commented Jan 24, 2021

Found this implementation in Chromium:

function generateUUID() {
  var array = new Uint8Array(16);
  window.crypto.getRandomValues(array);
  array[6] = 0x40 | (array[6] & 0x0f);
  array[8] = 0x80 | (array[8] & 0x3f);

  var UUID = "";
  for (var i = 0; i < 16; i++) {
    var temp = array[i].toString(16);
    if (temp.length < 2)
      temp = "0" + temp;
    UUID += temp;
    if (i == 3 || i == 5 || i == 7 || i == 9)
      UUID += "-";
  }
  return UUID;
};

I wonder if generating bytes instead of words reads a bit cleaner.

Copy link
Collaborator

@domenic domenic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking quite solid.

I will mention an alternate strategy, but I think yours is better since it reflects the underlying UUID structure more concretely. The alternative would be to flatten everything: i.e., the spec equivalent of:

let result = "";

result += computeA();
result += computeB();
result += "-";
result += computeTimeHighAndVersion();
result += "-";
result += computeClockSeqAndReservedClockSeqLow();
result += "-";
result += computeC();
result += computeD();
result += computeE();

return result;

index.html Outdated Show resolved Hide resolved
index.html Outdated Show resolved Hide resolved
index.html Outdated Show resolved Hide resolved
index.html Outdated Show resolved Hide resolved
index.html Outdated Show resolved Hide resolved
Copy link
Collaborator

@ctavan ctavan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I read the diff before reading your discussion @bcoe @domenic and my initial thought was if it really makes sense to introduce all these different time- and node-fields that the UUID RFC is referring to. They do make sense for v1 UUIDs and certainly reflect the general structure of UUIDs but I doubt that any real-world implementation of v4 UUIDs would really follow this idea.

After all even the RFC describes a much simpler algorithm which really boils down to ~3 lines of code e.g. see the chromium implementation you posted (i.e. set all 128 bits to cryptographically secure random values except for bits 6 and 7 as well as 12 through 15).

I'm just afraid that we're speccing along the spirit of the RFC but that real world implementations will much more likely follow a simpler approach in the end. So why risk this divergence in the first place?

index.html Outdated Show resolved Hide resolved
index.html Outdated Show resolved Hide resolved
@bcoe
Copy link
Collaborator Author

bcoe commented Jan 25, 2021

I'm just afraid that we're speccing along the spirit of the RFC but that real world implementations will much more likely follow a simpler approach in the end. So why risk this divergence in the first place?

@ctavan here's an approach that's taken in chromium today, that we could potentially just expose:

https://chromium.googlesource.com/chromium/src/+/refs/heads/master/base/guid.cc#86

  1. generate the 16 random byes.
  2. clear the version and reserved bits.
  3. return the hyphenated representation.

bcoe and others added 2 commits January 25, 2021 07:57
Co-authored-by: Christoph Tavan <dev@tavan.de>
Co-authored-by: Christoph Tavan <dev@tavan.de>
Copy link
Collaborator

@domenic domenic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking great; only editorial nits left.

index.html Outdated Show resolved Hide resolved
index.html Outdated Show resolved Hide resolved
index.html Outdated Show resolved Hide resolved
index.html Outdated Show resolved Hide resolved
index.html Outdated Show resolved Hide resolved
index.html Outdated Show resolved Hide resolved
@bcoe
Copy link
Collaborator Author

bcoe commented Jan 30, 2021

After all even the RFC describes a much simpler algorithm which really boils down to ~3 lines of code e.g. see the chromium implementation you posted

@domenic @ctavan does it make sense to land this, and then perhaps take another pass at the simplified algorithm that @ctavan suggests?

I think we'd be able to use a lot of the same language, just condense some of the steps together, perhaps the final step would be:

Return the concatenation of  « hexadecimal representation array[0], hexadecimal representation array[1], hexadecimal representation array[2], hexadecimal representation array[3], "-", hexadecimal representation array[4], hexadecimal representation array[5], "-" ...

👆 the one argument I'd make against this is it makes for a very long step in the algorithm.

Copy link
Collaborator

@domenic domenic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with nits! Indeed, it makes sense to land this and then consider non-normative refactorings.

index.html Show resolved Hide resolved
index.html Outdated Show resolved Hide resolved
Co-authored-by: Domenic Denicola <d@domenic.me>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Describe algorithm for randomUUID
3 participants