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