using System.Buffers.Text; using System.Runtime.InteropServices; namespace EnotaryoPH.Web.Common.Extensions { public static class GuidExtensions { private const char Dash = '-'; private const char EqualsChar = '='; private const byte ForwardSlashByte = (byte)'/'; private const char Plus = '+'; private const byte PlusByte = (byte)'+'; private const char Slash = '/'; private const char Underscore = '_'; public static string ToBase64String(this Guid guid) { Span guidBytes = stackalloc byte[16]; Span encodedBytes = stackalloc byte[24]; MemoryMarshal.TryWrite(guidBytes, ref guid); // write bytes from the Guid Base64.EncodeToUtf8(guidBytes, encodedBytes, out _, out _); Span chars = stackalloc char[22]; // replace any characters which are not URL safe // skip the final two bytes as these will be '==' padding we don't need for (var i = 0; i < 22; i++) { chars[i] = encodedBytes[i] switch { ForwardSlashByte => Dash, PlusByte => Underscore, _ => (char)encodedBytes[i], }; } var final = new string(chars); return final; } public static Guid ToGuidFromString(ReadOnlySpan id) { Span base64Chars = stackalloc char[24]; for (var i = 0; i < 22; i++) { base64Chars[i] = id[i] switch { '-' => Slash, '_' => Plus, _ => id[i] }; } base64Chars[22] = EqualsChar; base64Chars[23] = EqualsChar; Span idBytes = stackalloc byte[16]; Convert.TryFromBase64Chars(base64Chars, idBytes, out _); return new Guid(idBytes); } } }