收集几种生成顺序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条记录,结果如下
单从结果上看,第一种使用起来更方便些.
但这种方法有一个问题,就是在SQL SERVER中排序还是会乱,所以在需要排序的时候,需要对这种生成方式进行简单处理,增加一点代码
View Code
最终代码变为:
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(); }
相关文章推荐
- 收集几种生成顺序GUID的方法
- 几种有益与代码生成的好方法
- LINQ学习实战:查看LINQ生成SQL语句的几种方法
- 利用Java生成静态HMTL页面的方法收集
- 查看LINQ生成SQL语句的几种方法
- 几种生成不重复字符串的方法比较
- ASP中生成GUID的方法一种
- ASP生成静态HTML文件的几种方法比较
- 动态生成静态页面的几种方法
- 动态生成静态页面的几种方法
- php生成随机密码的几种方法
- 利用Java生成静态HMTL页面的方法收集
- 生成短GUID的两个方法
- 利用Java生成静态HMTL页面的方法收集
- 收集了一些静态生成页面的方法,自己也写了一下
- 网站生成静态页面的几种方法
- 网络上收集几种画圆及圆环的方法
- 生成GUID的方法
- [OpenNMS] 当妳有特殊的资料收集需求时,几种客制化的方法
- php生成随机密码的几种方法