using System; namespace CSharpVitamins { /// /// Represents a globally unique identifier (GUID) with a /// shorter string value. Sguid /// 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 Guid _guid; 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 { return _guid; } set { if (value != _guid) { _guid = value; _value = Encode(value); } } } /// /// Gets/sets the underlying base64 encoded string /// public string Value { get { return _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() { return _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() { return _guid.GetHashCode(); } #endregion #region NewGuid /// /// Initialises a new instance of the ShortGuid class /// /// public static ShortGuid NewGuid() { return 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) { Guid 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) { string 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("-", "+"); byte[] 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) { return !(x == y); } /// /// Implicitly converts the ShortGuid to it's string equivilent /// /// /// public static implicit operator string(ShortGuid shortGuid) { return shortGuid._value; } /// /// Implicitly converts the ShortGuid to it's Guid equivilent /// /// /// public static implicit operator Guid(ShortGuid shortGuid) { return shortGuid._guid; } /// /// Implicitly converts the string to a ShortGuid /// /// /// public static implicit operator ShortGuid(string shortGuid) { return new ShortGuid(shortGuid); } /// /// Implicitly converts the Guid to a ShortGuid /// /// /// public static implicit operator ShortGuid(Guid guid) { return new ShortGuid(guid); } #endregion } }