您的位置:首页 > 产品设计 > UI/UE

收集几种生成顺序GUID的方法

2017-07-05 09:09 351 查看


public static class Generator

    {

        [DllImport("rpcrt4.dll", SetLastError = true)]

        public static extern int UuidCreateSequential(out Guid guid);

        private const int RPC_S_OK = 0;

        public static Guid CreateRpcrt4Guid()

        {

            Guid guid;

            int result = UuidCreateSequential(out guid);

            if (result == RPC_S_OK)

                return guid;

            else

                return Guid.NewGuid();

        }

        public static Guid CreateSecuentialGuid()

        {

            byte[] uid = Guid.NewGuid().ToByteArray();

            byte[] binDate = BitConverter.GetBytes(DateTime.UtcNow.Ticks);

            byte[] secuentialGuid = new byte[uid.Length];

            secuentialGuid[0] = uid[0];

            secuentialGuid[1] = uid[1];

            secuentialGuid[2] = uid[2];

            secuentialGuid[3] = uid[3];

            secuentialGuid[4] = uid[4];

            secuentialGuid[5] = uid[5];

            secuentialGuid[6] = uid[6];

            // set the first part of the 8th byte to '1100' so    

            // later we'll be able to validate it was generated by us  

            secuentialGuid[7] = (byte)(0xc0 | (0xf & uid[7]));

            // the last 8 bytes are sequential,   

            // it minimizes index fragmentation  

            // to a degree as long as there are not a large   

            // number of Secuential-Guids generated per millisecond 

            secuentialGuid[9] = binDate[0];

            secuentialGuid[8] = binDate[1];

            secuentialGuid[15] = binDate[2];

            secuentialGuid[14] = binDate[3];

            secuentialGuid[13] = binDate[4];

            secuentialGuid[12] = binDate[5];

            secuentialGuid[11] = binDate[6];

            secuentialGuid[10] = binDate[7];

            return new Guid(secuentialGuid);

        }

        public static Guid CreateCombGuid()

        {

            byte[] guidArray = Guid.NewGuid().ToByteArray();

            DateTime baseDate = new DateTime(1900, 1, 1);

            DateTime now = DateTime.Now;

            // Get the days and milliseconds which will be used to build the byte string

            TimeSpan days = new TimeSpan(now.Ticks - baseDate.Ticks);

            TimeSpan msecs = now.TimeOfDay;

            // Convert to a byte array

            // Note that SQL Server is accurate to 1/300th of a millisecond so we divide by 3.333333

            byte[] daysArray = BitConverter.GetBytes(days.Days);

            byte[] msecsArray = BitConverter.GetBytes((long)(msecs.TotalMilliseconds / 3.333333));

            // Reverse the bytes to match SQL Servers ordering

            Array.Reverse(daysArray);

            Array.Reverse(msecsArray);

            // Copy the bytes into the guid

            Array.Copy(daysArray, daysArray.Length - 2, guidArray, guidArray.Length - 6, 2);

            Array.Copy(msecsArray, msecsArray.Length - 4, guidArray, guidArray.Length - 4, 4);

            return new Guid(guidArray);

        }

    }

每种方法只生成10条记录,结果如下

rpcrt4:Secuential:Comb:
f8373adb-cf34-11e2-be8d-d43d7e333b2c
f8373adc-cf34-11e2-be8d-d43d7e333b2c
f8373add-cf34-11e2-be8d-d43d7e333b2c
f8373ade-cf34-11e2-be8d-d43d7e333b2c
f8373adf-cf34-11e2-be8d-d43d7e333b2c
f8373ae0-cf34-11e2-be8d-d43d7e333b2c
f8373ae1-cf34-11e2-be8d-d43d7e333b2c
f8373ae2-cf34-11e2-be8d-d43d7e333b2c
f8373ae3-cf34-11e2-be8d-d43d7e333b2c
f8373ae4-cf34-11e2-be8d-d43d7e333b2c
e8edcc23-9c22-c3b1-04d1-08d07e5fad6c
15c44698-4b52-c379-04d1-08d07e5fad6c
a4abcb36-71e9-c2a2-04d1-08d07e5fad6c
bb03c46a-ab7a-ca27-04d1-08d07e5fad6c
e4b7b99e-2a8f-cb0a-04d1-08d07e5fad6c
26ac7070-3294-ca22-04d1-08d07e5fad6c
423a83c7-633a-c98c-04d1-08d07e5fad6c
f2480bdb-2260-c112-04d1-08d07e5fad6c
3b76a6dc-8534-cd29-04d1-08d07e5fad6c
e12fbfe7-dc1f-c57b-04d1-08d07e5fad6c

65d8b46f-ea29-41f8-af76-a1d600e29f85
2c95c4c2-aca4-46de-b842-a1d600e29f85
c6f054ea-dbb4-432c-aed3-a1d600e29f85
2b47c23c-ac18-467c-8c2d-a1d600e29f85
4dbe1536-ccb1-4fc4-b145-a1d600e29f85
cccd4c08-6c52-4b12-90fc-a1d600e29f85
f6f07bde-5108-43c0-9294-a1d600e29f85
921a018f-9545-447b-8c99-a1d600e29f85
fbc560a3-acbe-48da-9b06-a1d600e29f85
bbfbbe7f-2bc6-4bd7-bbae-a1d600e29f85
单从结果上看,第一种使用起来更方便些.
但这种方法有一个问题,就是在SQL SERVER中排序还是会乱,所以在需要排序的时候,需要对这种生成方式进行简单处理,增加一点代码





byte[] guidBytes = guid.ToByteArray();
Array.Reverse(guidBytes, 0, 4);
Array.Reverse(guidBytes, 4, 2);
Array.Reverse(guidBytes, 6, 2);


View Code
 最终代码变为:






public static Guid CreateRpcrt4Guid()
{
Guid guid;
int result = UuidCreateSequential(out guid);
if (result == RPC_S_OK)
{
byte[] guidBytes = guid.ToByteArray();
Array.Reverse(guidBytes, 0, 4);
Array.Reverse(guidBytes, 4, 2);
Array.Reverse(guidBytes, 6, 2);

return new Guid(guidBytes);
}
else
return Guid.NewGuid();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: