Skip to content

Instantly share code, notes, and snippets.

@vcsjones
Created June 15, 2024 20:38
Show Gist options
  • Save vcsjones/7e893b22555331d86698148d39b40235 to your computer and use it in GitHub Desktop.
Save vcsjones/7e893b22555331d86698148d39b40235 to your computer and use it in GitHub Desktop.
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
UUIDv7 uuid = new UUIDv7();
Console.WriteLine(uuid.ToString());
public readonly struct UUIDv7 {
private readonly InteriorStruct _interior;
public UUIDv7() {
InteriorStruct.Fill(ref _interior);
}
public byte[] GetBytes() => _interior.AsReadOnlySpan().ToArray();
public void CopyTo(Span<byte> destination) => _interior.AsReadOnlySpan().CopyTo(destination);
public override string ToString() => Convert.ToHexString(_interior.AsReadOnlySpan());
public readonly override int GetHashCode() {
HashCode hc = new();
hc.AddBytes(_interior.AsReadOnlySpan());
return hc.ToHashCode();
}
[InlineArray(SIZE)]
private struct InteriorStruct {
private const int SIZE = 16;
private byte _element;
public static void Fill(ref InteriorStruct uuid) {
Span<byte> value = MemoryMarshal.CreateSpan(ref uuid._element, SIZE);
RandomNumberGenerator.Fill(value);
long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
value[0] = (byte)((timestamp >> 40) & 0xFF);
value[1] = (byte)((timestamp >> 32) & 0xFF);
value[2] = (byte)((timestamp >> 24) & 0xFF);
value[3] = (byte)((timestamp >> 16) & 0xFF);
value[4] = (byte)((timestamp >> 8) & 0xFF);
value[5] = (byte)(timestamp & 0xFF);
// version and variant
value[6] = (byte)((value[6] & 0x0F) | 0x70);
value[8] = (byte)((value[8] & 0x3F) | 0x80);
}
[UnscopedRef]
internal ReadOnlySpan<byte> AsReadOnlySpan() => MemoryMarshal.CreateReadOnlySpan(ref _element, SIZE);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment