How to seed GUID generation?

19,040

All you really need to do in your GenerateSeededGuid method is to create a 128-bit random number and the convert it to a Guid. Something like:

public Guid GenerateSeededGuid(int seed)
{
  var r = new Random(seed);
  var guid = new byte[16];
  r.NextBytes(guid);

  return new Guid(guid);
}
Share:
19,040
CJ7
Author by

CJ7

Updated on June 04, 2022

Comments

  • CJ7
    CJ7 almost 2 years

    What would be the easiest way to code a function in .NET to generate a GUID based on a seed so that I can have greater confidence about its uniqueness?

    string GenerateSeededGuid(int seed) { /* code here */ }
    

    Ideally, the seed would come from CryptGenRandom which describes its random number generation as follows:

    The data produced by this function is cryptographically random. It is far more random than the data generated by the typical random number generator such as the one shipped with your C compiler.

    This function is often used to generate random initialization vectors and salt values.

    Software random number generators work in fundamentally the same way. They start with a random number, known as the seed, and then use an algorithm to generate a pseudo-random sequence of bits based on it. The most difficult part of this process is to get a seed that is truly random. This is usually based on user input latency, or the jitter from one or more hardware components.

    With Microsoft CSPs, CryptGenRandom uses the same random number generator used by other security components. This allows numerous processes to contribute to a system-wide seed. CryptoAPI stores an intermediate random seed with every user. To form the seed for the random number generator, a calling application supplies bits it might have—for instance, mouse or keyboard timing input—that are then combined with both the stored seed and various system data and user data such as the process ID and thread ID, the system clock, the system time, the system counter, memory status, free disk clusters, the hashed user environment block. This result is used to seed the pseudorandom number generator (PRNG). [...] If an application has access to a good random source, it can fill the pbBuffer buffer with some random data before calling CryptGenRandom. The CSP then uses this data to further randomize its internal seed. It is acceptable to omit the step of initializing the pbBuffer buffer before calling CryptGenRandom.

  • Admin
    Admin over 11 years
    +1 For "from a seed", although 1) this can end up with invalid UUIDs (wrong version bits) and 2) generates more collisions as the seed is limited in range; GUIDs are designed to "have a very low collision chance" so there is no reason to inherently believe that a custom one-off Randomly generated approach would work better or be more random that a GUIDv4 found Windows 2k+
  • Sani Singh Huttunen
    Sani Singh Huttunen over 11 years
    @pst: I agree. Personally I see no reason not to use NewGuid.
  • Abhishek
    Abhishek over 6 years
    Unit tests that do approvals of whole docs - those benefit from this technique. Thanks!
  • Enigmativity
    Enigmativity over 5 years
    Guids are not guaranteed to be random, only unique.
  • EKS
    EKS about 4 years
    GetHashCode does not always return the same value for the same input. It can for example change with restart of the application.