Miguel Moura
Miguel Moura

Reputation: 39484

Create a Sequential Guid from Integers

I need to create a few sequential guids:

00000000-0000-0000-00000000000000001
00000000-0000-0000-00000000000000002
...
00000000-0000-0000-00000000000000011

I need to do this just for a few tests. I do not need thousands of Guids ...

I tried the following but I get a problem when I reach 11.

for (Int32 i = 1; i < 12; i++) {
  Guid guid = new Guid(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (Byte)i);
}

Any way to solve this?

Maybe transforming the int into a string with format and then to Guid?

I really don't know how to solve this ...

Thank You, Miguel

Upvotes: 0

Views: 540

Answers (5)

musefan
musefan

Reputation: 48435

You guid is actually invalid, it should be in the format 00000000-0000-0000-0000-000000000000.

With that in mind, and assuming you are not going to have more than 12 digits changing, you can just do some string formatting:

for (Int32 i = 1; i < 12; i++) 
{
    string s = "00000000-0000-0000-0000-" + i.ToString("D12");
    Guid guid = new Guid(s);
}

Of course if you insist on your original format, then the following line will do that:

string s = "00000000-0000-0000-" + i.ToString("D17");

Upvotes: 4

Danny Varod
Danny Varod

Reputation: 18118

You can use 'shift left' (>>) and 'bitwise and' (&) for this e.g.

short lowest16bit = i & 0xffff;
byte next8bit = (i>>8) & 0xff;

To create a GUID you need 128bits, a regular int is 32bit a long is 64bit.

Using the constructor you used (MSDN):

Guid(int a, short b, short c,
    byte d, byte e, byte f, byte g, byte h, byte i, byte j, byte k);

You can create a non-random Guid with 32 non-zero bits from an int using:

int i;
Guid g = new Guid(i, (short)0, (byte)0, (byte)0, (byte)0, ...

You can create a non-random Guid with 64 non-zero bits from a long using:

long l;
Guid g = new Guid((l>>32) & 0xffffffff, (l>>16) & 0xffff, l & 0xffff, (byte)0, ....);

and etc.

Upvotes: 1

Charleh
Charleh

Reputation: 14002

This should work to give you a shedload - if you need any more than that then tough!

for (long i = 1; i < long.MaxValue; i++)
{
    var bytes = new byte[16];
    var lngBytes = BitConverter.GetBytes(i);
    Array.Copy(lngBytes, bytes, 8);
    Array.Reverse(bytes);
    var guid = new Guid(bytes);
}

(Actually you'll probably hit an out of memory exception if you use long.MaxValue! So use something sensible!)

Edit:

Ok I just had to do it anyway:

var gids = new List<Guid>();

for (long i = 1; i < 10000; i++)
{ 
     // Skip any values that we don't want
     if ((float)i / 16 % 1 >= 0.625)
     {
         i += 5;
         continue;
     }

     var bytes = new byte[16];
     var lngBytes = BitConverter.GetBytes(i);
     Array.Copy(lngBytes, bytes, 8);
     Array.Reverse(bytes);
     gids.Add(new Guid(bytes));
 }

A nice mathematical way of doing it.. :) (argh it actually dies after 100 iterations, but I'm sure I just need to tweak the skip formula!)

Upvotes: 0

SimonGoldstone
SimonGoldstone

Reputation: 5216

The thing is, the maximum value for an Int32 expressed in hex is only 0x7FFFFFFF so there will be lots of empty room in the guid.

As @Yosi said, this isn't really what they're intended for, but on the basis that this is what you asked for, what about this:

 var guid = "00000000-0000-0000-0000-" + i.ToString("D12")

And to generate a sequence, something like this:

 for (int i = 0; i < 2000; i++)
 {
     var guidStr = "00000000-0000-0000-0000-" + i.ToString("D12");
     var guid = new Guid(guidStr);
     Console.WriteLine(guid);
 }

Upvotes: 1

Charles Bretana
Charles Bretana

Reputation: 146557

I do not recommend using guids as keys. but, you should check out

COMB Guids

and

This SO Question

Using Sql Server syntax, it generates sequential Guids using the following algorithm.

DECLARE @aGuid UNIQUEIDENTIFIER

SET @aGuid = CAST(CAST(NEWID() AS BINARY(10)) 
           + CAST(GETDATE() AS BINARY(6)) AS UNIQUEIDENTIFIER)

Upvotes: 0

Related Questions