public class IdGenerate
{
private long _counter = 0;
private static long _lastTimeStamp=DateTime.Now.GetTimeStamp();
private static IdGenerate idGenerate=new IdGenerate();
private long Hash(long timeStamp,long counter)
{
long hash = 0L;
int t=0, c=0;
for(var i = 0; i < 52; i++)
{
long bit = 0;
if (i>0& i % 5 == 0)
{
bit = counter >> c++;
}
else
{
bit = timeStamp >> t++;
}
hash|=(bit&1)<<i;
}
return hash;
}
public long GetId()
{
long now=DateTime.Now.GetTimeStamp();
lock (this)
{
if (_lastTimeStamp == now) {
_counter++;
if(_counter> 0b1_1111_1111)
{
_counter=0;
do
{
Thread.Yield();
now = DateTime.Now.GetTimeStamp();
} while (_lastTimeStamp < now);
}
_lastTimeStamp = now;
}
else
{
_lastTimeStamp = now;
_counter=0;
}
//_counter = 0;
return Hash(now,_counter);
}
}
public string GetBase64Id()
{
var r = new Random();
byte[] bytes= new byte[9];
bytes[0] = (byte)r.Next(255);
var id=BitConverter.GetBytes(GetId());
//Array.Reverse(id);
id.CopyTo(bytes, 1);
return Convert.ToBase64String(bytes);
}
public static long NextId()
{
return idGenerate.GetId();
}
public static string NextBase64Id()
{
return idGenerate.GetBase64Id();
}
}
用法
[Test]
public void TestIdGenerate()
{
var idg=new IdGenerate();
for(var i = 0; i < 60; i++)
{
//Console.WriteLine(idg.GetId().ToString("X16"));
Console.WriteLine(idg.GetId().ToString("X16"));
}
}
[Test]
public void TestIdGenerateBase6()
{
var idg = new IdGenerate();
for (var i = 0; i < 60; i++)
{
//Console.WriteLine(idg.GetId().ToString("X16"));
Console.WriteLine(idg.GetBase64Id());
}
}