2

I saw that I can create name-based UUID / deterministic GUID, see https://stackoverflow.com/a/5657517/7556646.

Example of a non-name-based UUID:

System.Guid id1 = System.Guid.NewGuid()
// id1 = {780dc51b-8eb3-4d66-b76d-8ab44e1311e6} for example

Example of a named-based UUID:

string filePath = "Test";
System.Guid id2 = GuidUtility.Create(GuidUtility.UrlNamespace, filePath);
// id2 = {64ad81d8-15e2-5110-9024-83c64dc485f9}

Now I've the following question: Is there a way for example in C# to find out if GUID is a name-based UUID or a non-named-based UUID?

Wollmich
  • 1,616
  • 1
  • 18
  • 46
  • 2
    it would help if you pasted the output of each uuid type below the corresponding code – santiago arizti Feb 07 '18 at 16:24
  • 1
    Not a complete answer, but if someone else wants to include it in theirs, [this section](https://github.com/LogosBible/Logos.Utility/blob/master/src/Logos.Utility/GuidUtility.cs#L62-L66) of `GuidUtility.Create()` appears to leave a signature that you can check for in name-based UUIDs. – Patrick Roberts Feb 07 '18 at 16:31

1 Answers1

3

In general for non-named-based guid the 13th digit (right after the second dash) will be a 4 and for named based it will be a 3 or 5.

This isn't universally true but will be for the code you are using.

"0b5415ec-657c-4a80-9199-f7993aff3908"

"275b74ef-e22a-59d6-8b2c-4face1410f59"

The version number is decribed in RFC 4122:

   0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                          time_low                             |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |       time_mid                |         time_hi_and_version   |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |clk_seq_hi_res |  clk_seq_low  |         node (0-1)            |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                         node (2-5)                            |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

The version number is in the most significant 4 bits of the time stamp (bits 4 through 7 of the time_hi_and_version field). The following table lists the currently-defined versions for this UUID variant:

  1. The time-based version specified in this document.
  2. DCE Security version, with embedded POSIX UIDs.
  3. The name-based version specified in this document that uses MD5 hashing.
  4. The randomly or pseudo-randomly generated version specified in this document.
  5. The name-based version specified in this document that uses SHA-1 hashing.

With the following code you could check if a GUID is name-based:

public static bool IsNameBased(Guid id)
{
    byte version = GetVersion(id);
    return version == 3 || version == 5;
}

public static byte GetVersion(Guid id)
{
    byte[] byte_array = id.ToByteArray();
    byte version = (byte)(byte_array[7] >> 4);
    return version;
}
Community
  • 1
  • 1
Charlie
  • 46
  • 4
  • 1
    Going off of memory, I believe you are correct, but for credibility it would benefit you to cite a well-known source to support your claim. Consider [edit]ing your answer to include a link to a source that explains this convention, and use a `>` quoteblock to include relevant information from the link. – Patrick Roberts Feb 07 '18 at 17:13
  • 1
    Version bits are described in [RFC 4122](https://tools.ietf.org/html/rfc4122#section-4.1.3) – Antti Leppänen Feb 07 '18 at 17:37
  • 1
    Wow, I always thought GUIDs are completely random. I never realized (I checked, you were right) that one digit is constant. – Manfred Radlwimmer Feb 08 '18 at 08:45