using System; namespace PKISharp.WACS.DomainObjects { /// /// Represents a globally unique identifier (GUID) with a /// shorter string value. Sguid /// Taken from https://www.singular.co.nz/2007/12/shortguid-a-shorter-and-url-friendly-guid-in-c-sharp/ /// public struct ShortGuid { #region Static /// /// A read-only instance of the ShortGuid class whose value /// is guaranteed to be all zeroes. /// public static readonly ShortGuid Empty = new ShortGuid(Guid.Empty); #endregion #region Fields private Guid _guid; private string _value; #endregion #region Contructors /// /// Creates a ShortGuid from a base64 encoded string /// /// The encoded guid as a /// base64 string public ShortGuid(string value) { _value = value; _guid = Decode(value); } /// /// Creates a ShortGuid from a Guid /// /// The Guid to encode public ShortGuid(Guid guid) { _value = Encode(guid); _guid = guid; } #endregion #region Properties /// /// Gets/sets the underlying Guid /// public Guid Guid { get => _guid; set { if (value != _guid) { _guid = value; _value = Encode(value); } } } /// /// Gets/sets the underlying base64 encoded string /// public string Value { get => _value; set { if (value != _value) { _value = value; _guid = Decode(value); } } } #endregion #region ToString /// /// Returns the base64 encoded guid as a string /// /// public override string ToString() => _value; #endregion #region Equals /// /// Returns a value indicating whether this instance and a /// specified Object represent the same type and value. /// /// The object to compare /// public override bool Equals(object obj) { if (obj is ShortGuid) { return _guid.Equals(((ShortGuid)obj)._guid); } if (obj is Guid) { return _guid.Equals((Guid)obj); } if (obj is string) { return _guid.Equals(((ShortGuid)obj)._guid); } return false; } #endregion #region GetHashCode /// /// Returns the HashCode for underlying Guid. /// /// public override int GetHashCode() => _guid.GetHashCode(); #endregion #region NewGuid /// /// Initialises a new instance of the ShortGuid class /// /// public static ShortGuid NewGuid() => new ShortGuid(Guid.NewGuid()); #endregion #region Encode /// /// Creates a new instance of a Guid using the string value, /// then returns the base64 encoded version of the Guid. /// /// An actual Guid string (i.e. not a ShortGuid) /// public static string Encode(string value) { var guid = new Guid(value); return Encode(guid); } /// /// Encodes the given Guid as a base64 string that is 22 /// characters long. /// /// The Guid to encode /// public static string Encode(Guid guid) { var encoded = Convert.ToBase64String(guid.ToByteArray()); encoded = encoded .Replace("/", "_") .Replace("+", "-"); return encoded.Substring(0, 22); } #endregion #region Decode /// /// Decodes the given base64 string /// /// The base64 encoded string of a Guid /// A new Guid public static Guid Decode(string value) { value = value .Replace("_", "/") .Replace("-", "+"); var buffer = Convert.FromBase64String(value + "=="); return new Guid(buffer); } #endregion #region Operators /// /// Determines if both ShortGuids have the same underlying /// Guid value. /// /// /// /// public static bool operator ==(ShortGuid x, ShortGuid y) { if ((object)x == null) { return (object)y == null; } return x._guid == y._guid; } /// /// Determines if both ShortGuids do not have the /// same underlying Guid value. /// /// /// /// public static bool operator !=(ShortGuid x, ShortGuid y) => !(x == y); /// /// Implicitly converts the ShortGuid to it's string equivilent /// /// /// public static implicit operator string(ShortGuid shortGuid) => shortGuid._value; /// /// Implicitly converts the ShortGuid to it's Guid equivilent /// /// /// public static implicit operator Guid(ShortGuid shortGuid) => shortGuid._guid; /// /// Implicitly converts the string to a ShortGuid /// /// /// public static implicit operator ShortGuid(string shortGuid) => new ShortGuid(shortGuid); /// /// Implicitly converts the Guid to a ShortGuid /// /// /// public static implicit operator ShortGuid(Guid guid) => new ShortGuid(guid); #endregion } }