using System.Security.Cryptography; namespace Mizuki.Helpers; /// /// An AT protocol time-based ID. /// public readonly struct Tid { /// /// The Base32 sort alphabet. /// private const string Base32SortAlphabet = "234567abcdefghijklmnopqrstuvwxyz"; /// /// The TID value. /// public readonly string Value; /// /// Constructs a TID from an integer representation of the TID. /// /// The TID value. private Tid(ulong tid) { Value = NumericTidToStringTid(tid); } /// /// Constructs a new TID for the current time. /// /// The current time. public static Tid NewTid() { var microseconds = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() * 1000; var randomness = (uint)RandomNumberGenerator.GetInt32(int.MaxValue); var value = (ulong)(((microseconds & 0x1F_FFFF_FFFF_FFFF) << 10) | (randomness & 0x3FF)); return new Tid(value); } /// /// An empty TID. /// public static Tid Empty => new Tid(0); /// /// Converts a numeric TID to a string TID. /// /// The numeric TID. /// The string TID. private static string NumericTidToStringTid(ulong tid) { var value = 0x7FFF_FFFF_FFFF_FFFF & tid; var output = ""; for (var i = 0; i < 13; i++) { output = Base32SortAlphabet[(int)(value & 0x1F)] + output; value >>= 5; } return output; } /// public override string ToString() { return Value; } }