从整数创建顺序Guid

时间:2013-11-06 16:54:28

标签: c#

我需要创建一些顺序guid:

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

我只需要进行一些测试即可。我不需要成千上万的Guids ......

我尝试了以下但是当我达到11时我遇到了问题。

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

有什么方法可以解决这个问题?

也许将int转换为带格式的字符串然后转换为Guid?

我真的不知道如何解决这个问题......

谢谢你, 米格尔

5 个答案:

答案 0 :(得分:4)

你guid实际上是无效的,它应该采用00000000-0000-0000-0000-000000000000格式。

考虑到这一点,并且假设你不会有超过12位数的变化,你可以只做一些字符串格式化:

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

当然,如果您坚持原始格式,那么以下行将会这样做:

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

答案 1 :(得分:1)

你可以使用'shift left'(&gt;&gt;)和'bitwise'和'(&amp;)来表示这种情况。

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

要创建GUID,您需要128位,常规int为32位,长度为64位。

使用您使用的构造函数(MSDN):

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

您可以使用以下命令从int创建一个包含32个非零位的非随机Guid:

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

您可以使用以下方法创建一个包含64个非零位的非随机Guid:

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

等等。

答案 2 :(得分:1)

问题是,以十六进制表示的Int32的最大值仅为0x7FFFFFFF,因此guid中会有很多空的空间。

正如@Yosi所说,这并不是他们想要的,但是基于这就是你要求的,这是怎么回事:

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

生成一个序列,如下所示:

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

答案 3 :(得分:0)

我不建议使用guids作为键。但是,你应该看看

COMB Guids

This SO Question

使用Sql Server语法,它使用以下算法生成顺序Guids。

DECLARE @aGuid UNIQUEIDENTIFIER

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

答案 4 :(得分:0)

这应该可以帮助你解决问题 - 如果你需要更多的东西那么艰难!

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);
}

(实际上,如果你使用long.MaxValue,你可能会遇到内存不足的异常!所以请使用合理的东西!)

编辑:

好的,我还是必须这样做:

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));
 }

这是一个很好的数学方法.. :)(实际上它经过100次迭代后死亡,但我确定我只需要调整跳过公式!)