/************************************************************
* Description: Guid帮助类,用于生产连续的Guid
* Create Time: 2019-02-25
* Author:zh.z
* Version: v1.0.1
************************************************************/
using System;
using System.Security.Cryptography;
namespace BOZHON.TSAMO.Common
{
public class GuidHelper
{
///
/// 获取GUID字符串(36位)
///
/// 是否大写(默认fasle)
/// 类型
///
public static string Get36(bool upper = false, SequentialGuidType sequentialGuidType = SequentialGuidType.SequentialAsBinary)
{
Guid guid = SequentialGuidGenerator.NewSequentialGuid(sequentialGuidType);
string tmp = guid.ToString();
return upper ? tmp.ToUpper() : tmp.ToLower();
}
///
/// 获取GUID字符串 (获取32位不包含“-”号的GUID字符串)
///
/// 是否大写
/// 类型
///
public static string Get32(bool upper = true, SequentialGuidType sequentialGuidType = SequentialGuidType.SequentialAsBinary)
{
Guid guid = SequentialGuidGenerator.NewSequentialGuid(sequentialGuidType);
string tmp = guid.ToString("N");
return upper ? tmp.ToUpper() : tmp.ToLower();
}
///
/// 获取GUID字符串 (获取32位包含“-”号的GUID字符串)
///
/// 是否大写
/// 类型
///
public static string Get32_(bool upper = true, SequentialGuidType sequentialGuidType = SequentialGuidType.SequentialAsBinary)
{
Guid guid = SequentialGuidGenerator.NewSequentialGuid(sequentialGuidType);
string tmp = guid.ToString("D");
return upper ? tmp.ToUpper() : tmp.ToLower();
}
///
/// 获取有序的唯一ID。
///
///
public static Guid GenerateComb(SequentialGuidType sequentialGuidType = SequentialGuidType.SequentialAsBinary)
{
return SequentialGuidGenerator.NewSequentialGuid(sequentialGuidType);
}
///
/// 根据枚举生成不同的有序GUID
/// http://www.codeproject.com/Articles/388157/GUIDs-as-fast-primary-keys-under-multiple-database
///
private static class SequentialGuidGenerator
{
private static readonly RNGCryptoServiceProvider Rng = new RNGCryptoServiceProvider();
public static Guid NewSequentialGuid(SequentialGuidType guidType)
{
var randomBytes = new byte[10];
Rng.GetBytes(randomBytes);
var timestamp = DateTime.UtcNow.Ticks / 10000L;
var timestampBytes = BitConverter.GetBytes(timestamp);
if (BitConverter.IsLittleEndian)
{
Array.Reverse(timestampBytes);
}
var guidBytes = new byte[16];
switch (guidType)
{
case SequentialGuidType.SequentialAsString:
case SequentialGuidType.SequentialAsBinary:
Buffer.BlockCopy(timestampBytes, 2, guidBytes, 0, 6);
Buffer.BlockCopy(randomBytes, 0, guidBytes, 6, 10);
// If formatting as a string, we have to reverse the order
// of the Data1 and Data2 blocks on little-endian systems.
if (guidType == SequentialGuidType.SequentialAsString && BitConverter.IsLittleEndian)
{
Array.Reverse(guidBytes, 0, 4);
Array.Reverse(guidBytes, 4, 2);
}
break;
case SequentialGuidType.SequentialAtEnd:
Buffer.BlockCopy(randomBytes, 0, guidBytes, 0, 10);
Buffer.BlockCopy(timestampBytes, 2, guidBytes, 10, 6);
break;
default:
throw new ArgumentOutOfRangeException("guidType", guidType, null);
}
return new Guid(guidBytes);
}
}
}
///
/// 有序GUID的类型
/// 1. MSSQL uniqueidentifier SequentialAtEnd
/// 2. MySQL char(36) SequentialAsString
/// 3. Oracle raw(16) SequentialAsBinary
/// 4. PostgreSQL uuid SequentialAsString
///
public enum SequentialGuidType
{
///
/// MySQL,PostgreSQL
///
SequentialAsString,
///
/// Oracle
///
SequentialAsBinary,
///
/// MSSQL
///
SequentialAtEnd
}
}