Michael Stum
Michael Stum

Reputation: 180874

Creating GUIDs with a set Prefix

i wonder if there is a way to generate valid GUIDs/UUIDs where the first (or any part) part is a user-selected prefix.

I.e., the GUID has the format AAAAAAAA-BBBB-CCCC-DDDD-DDDDDDDDDDDD, and I want to set any part to a pre-defined value (ideally the AAA's). The goal is to have GUIDs still globally unique, but they do not need to be cryptographically safe.

Upvotes: 3

Views: 6899

Answers (6)

tfinniga
tfinniga

Reputation: 6849

I recently had a similar need - I needed a GUID that was:

  • created by the standard guid algorithms, and therefore has a chance of being globally unique
  • has a defined prefix.

As you might imagine, I was doing something I shouldn't have.

You mention in one of your comments that you could just let the GUID generator run until it happens to hit upon a guid with the prefix you need. That's the tactic I took. Here's the code:

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string target_prefix = "dead";

            while (true)
            {
                Guid g = Guid.NewGuid();
                string gs = g.ToString();
                if (gs.Substring(0, target_prefix.Length) == target_prefix)
                {
                    Console.WriteLine("Match: " + gs);
                }
                else
                {
                    //Console.WriteLine("Mismatch: " + gs);
                }
            }
        }
    }
}

For smaller prefixes it produces matches more quickly. I bet it's 16x as long for every digit of target prefix.

Upvotes: 1

Michael Stum
Michael Stum

Reputation: 180874

Thanks. My problem with these attempts is that they are not guaranteed to be globally unique, as Raymond Chen pointed out. I was wondering if there is another algorithm that generates GUIDs that are unique. I remember that there used to be implementations that used a Timestamp and/or the NIC MAC Address, but they are not used anymore since they are not cryptographic strong and/or there were privacy concerns.

I wonder: If I just make up my own, i should be fine? According to Wikipedia:

One to three of the most significant bits of the second byte in Data 4 define the type variant of the GUID:

Pattern Description
0 Network Computing System backward compatibility
10 Standard
110 Microsoft Component Object Model backward compatibility; this includes the GUID's for important interfaces like IUnknown and IDispatch.
111 Reserved for future use.

The most significant four bits of Data3 define the version number, and the algorithm used.

So if I make up something in Data3/Data4, i would normally create my own implementation that should not clash with any other GUID, but of course there is always a bit of risk associated with that, so before I do that I wanted to check if there is an older/not anymore used algorhithm that generates true Unique Ids.

Upvotes: 0

Oliver Friedrich
Oliver Friedrich

Reputation: 9240

You can simply create a Guid, and change the prefix to be like you whish it to be. Have seen this in an OS-Project, where same question was thrown and solved by generating so many guids until one matches the wished prefix (ugh!).

Guid g = Guid.NewGuid(); string gs = g.ToString(); Guid f = new Guid(string.Format("{0}-{1}", "AAAAAAAA", gs.Substring(gs.IndexOf('-') + 1)));

Not nice, but works.

What bothered me from other posts in this subject is, that a guid shall be globally unique, thats wrong in all cases, it has just enough room to generaty unique guids, but nothing guaranteed for global uniquely. Even time is not considered in generating a guid.

Upvotes: 1

Mark Brackett
Mark Brackett

Reputation: 85625

Hmmm...so, you'd basically like a 12 byte GUID? Since, once you remove the uniqueness of the first 4 bytes (your AAA's), you've broken the existing algorithm - you'll need to come up with your own algorithm.

According to the relevant RFC, the GUID format breaks down to:

  UUID                   = time-low "-" time-mid "-"
                           time-high-and-version "-"
                           clock-seq-and-reserved
                           clock-seq-low "-" node
  time-low               = 4hexOctet
  time-mid               = 2hexOctet
  time-high-and-version  = 2hexOctet
  clock-seq-and-reserved = hexOctet
  clock-seq-low          = hexOctet
  node                   = 6hexOctet
  hexOctet               = hexDigit hexDigit
  hexDigit =
        "0" / "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9" /
        "a" / "b" / "c" / "d" / "e" / "f" /
        "A" / "B" / "C" / "D" / "E" / "F"

The only static data in there is version (4 bits) and reserved/variant (2-3 bits). I don't see that they allowed for any "user specified" versions, but I'd say you'll be safe for the foreseeable future if you use 1111 as your version identifier. The existing versions are in section 4.1.3, but only 5 have been defined so far...that gives you 11 more revisions before collision.

So, if you can live with 6 or 7 bits of distinctness, a combination of Guid.NewGuid().ToByteArray() and creating a new Guid after your bit fiddling should get you there.

Upvotes: 5

MSalters
MSalters

Reputation: 179779

Sorry, you want too much from a GUID. Summarizing from both your question and your own answer/update, you want it to

  • 1 be a GUID
  • 2 not collide with any other GUID (be globally unique)
  • 3 Ignore the standard on the interpretation of the first bits, using a reserved value
  • 4 Use a personal scheme for the remaining bits

This is impossible, proof: If it was possible, I could generate a GUID G1 and you could generate another GUID G2. Since we both ignore the standard and use the same reserved prefix, and my personal scheme for the other bits is outside your control, my GUID G1 can clash with your GUID G2. The non-collision propery of GUIDs follows from sticking to the GUID standard.

The mechanisms to prevent collisions are indeed inherently privacy-sensitive. If I generate at random a GUID G1, I can guarantee that random GUID is unique if two conditions are satisfied:

  • 1 It's a member of the subset of GUIDs under my control and
  • 2 I didn't generate the GUID before.

For GUIDs outside the subset under your control, you cannot guarantee (2). But how do you assign non-overlapping subsets of GUIDs to a single person? Using the MAC of a NIC is a simple, effective way. Other means are also possible. But in any case, the mere existence of such a subset is privacy-implicating. It's got to belong to someone, and I must be able to determine whether that's me or someone else. It's a bit harder to prove whether two random GUIDs G1 and G2 belong to the same subset (ie. person) but the current schemes (which you object to) do not try to hide that.

Upvotes: 5

Samiksha
Samiksha

Reputation: 6182

Not possible to create GUIDs/UUIDs where the first (or any part) part is a user-selected prefix , whereas you can write your own function to create a unique id wid same number (36/38) of characters...

Upvotes: 2

Related Questions