I am trying to generate a unique ID for the primary key of a table and I am using DateTime.Now.Ticks
for it. That\'s a requirement for now we can\'t use Ident
Creating a unique sequential Id based of DateTime.Now.Ticks is challenging. But can be done if you consider the points in @ZunTzu's excellent answer.
The code below is used by the Kestrel HTTP server. It's used when Kestrel generates request IDs for traces.
internal static class CorrelationIdGenerator
{
private static readonly string _encode32Chars = "0123456789ABCDEFGHIJKLMNOPQRSTUV";
private static long _lastId = DateTime.UtcNow.Ticks;
public static string GetNextId() => GenerateId(Interlocked.Increment(ref _lastId));
private static unsafe string GenerateId(long id)
{
char* charBuffer = stackalloc char[13];
charBuffer[0] = _encode32Chars[(int)(id >> 60) & 31];
charBuffer[1] = _encode32Chars[(int)(id >> 55) & 31];
charBuffer[2] = _encode32Chars[(int)(id >> 50) & 31];
charBuffer[3] = _encode32Chars[(int)(id >> 45) & 31];
charBuffer[4] = _encode32Chars[(int)(id >> 40) & 31];
charBuffer[5] = _encode32Chars[(int)(id >> 35) & 31];
charBuffer[6] = _encode32Chars[(int)(id >> 30) & 31];
charBuffer[7] = _encode32Chars[(int)(id >> 25) & 31];
charBuffer[8] = _encode32Chars[(int)(id >> 20) & 31];
charBuffer[9] = _encode32Chars[(int)(id >> 15) & 31];
charBuffer[10] = _encode32Chars[(int)(id >> 10) & 31];
charBuffer[11] = _encode32Chars[(int)(id >> 5) & 31];
charBuffer[12] = _encode32Chars[(int)id & 31];
return new string(charBuffer, 0, 13);
}
}
The key take aways are:
DateTime.UtcNow.Ticks
as a 'seed'.When trying to do this myself for a IoT project I discovered this code when reading this excellent blog post, aptly named Generating IDs in C# 'safely' and efficiently.