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;
}
}