Skip to content

Instantly share code, notes, and snippets.

@MichalBrylka
Created November 17, 2024 14:28
Show Gist options
  • Save MichalBrylka/4dfbb5cb128b43d266c26ac370744469 to your computer and use it in GitHub Desktop.
Save MichalBrylka/4dfbb5cb128b43d266c26ac370744469 to your computer and use it in GitHub Desktop.
Guid.CreateVersion7
using System.Runtime.InteropServices;
var now = DateTimeOffset.UtcNow;
TryGenerate(() => Guid.NewGuid(), " v4");
TryGenerate(() => Guid.CreateVersion7(now), " v7");
TryGenerate(() => CreateVersion7(now), "MBv7");
TryGenerate(() => Ulid.NewUlid(now).ToGuid(), "Ulid");
static void TryGenerate(Func<Guid> generator, string name)
{
for (var i = 0; i < 5; i++)
{
var guid = generator();
Console.WriteLine($"{name}: {guid}");
}
}
/*Output
v4: 9c695f61-6c00-41d7-a191-efc8b2d6b5c4
v4: 5b8a53e7-01f7-4f89-aa1c-325b1b03d8d1
v4: 4d7c6daf-91b1-4d44-a277-ba5626b17f8c
v4: e3039fc9-0dbe-406b-83a9-7aaebe97aa4f
v4: f5bf0aa8-e865-4916-97a4-9ae965e0b82f
v7: 01933a32-b2b8-7dc2-a605-1f49057b06be
v7: 01933a32-b2b8-77d3-9b69-a7ce07550dc9
v7: 01933a32-b2b8-78b9-8d25-325ec1eeb7f1
v7: 01933a32-b2b8-7fb3-95cd-4470245d95f1
v7: 01933a32-b2b8-79e0-90f3-912566945738
Ulid: 01933a32-b2b8-835b-4e7a-be129fb30dda
Ulid: 01933a32-b2b8-e09c-16d9-e1118adaf181
Ulid: 01933a32-b2b8-bfd4-fac0-18b026635ce9
Ulid: 01933a32-b2b8-a481-8d60-eef345331de0
Ulid: 01933a32-b2b8-1e49-7dba-22788da45197
*/
static Guid CreateVersion7(DateTimeOffset? timestamp)
{
const byte Variant10xxMask = 0xC0, Variant10xxValue = 0x80;
const ushort VersionMask = 0xF000, Version7Value = 0x7000;
Guid result = Guid.NewGuid();
timestamp ??= DateTimeOffset.UtcNow;
long unix_ts_ms = timestamp.Value.ToUnixTimeMilliseconds();
ArgumentOutOfRangeException.ThrowIfNegative(unix_ts_ms, nameof(timestamp));
Span<byte> bytes = stackalloc byte[16];
MemoryMarshal.TryWrite(bytes, in result);
//var a = MemoryMarshal.Read<int>(bytes[..4]);
var a = (int)(unix_ts_ms >> 16);
MemoryMarshal.Write(bytes[..4], a);
//var b = MemoryMarshal.Read<short>(bytes[4..6]);
var b = (short)(unix_ts_ms);
MemoryMarshal.Write(bytes[4..6], b);
var cBytes = bytes[6..8];
var c = MemoryMarshal.Read<short>(cBytes);
MemoryMarshal.Write(cBytes, (short)((c & ~VersionMask) | Version7Value));
//var d = bytes[8];
bytes[8] = (byte)((bytes[8] & ~Variant10xxMask) | Variant10xxValue);
result = new Guid(bytes, false);
return result;
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Ulid" Version="1.3.4" />
</ItemGroup>
</Project>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment