Il arrive, dans certains scénario, que le Guid n'est pas adapté: il est trop long ou il n'est pas très joli! Mais lorsque l'on a gouté au Guid, il est difficile de s'en passer. Il existe un moyen de raccourcir un Guid: le ShortGuid!

Le ShortGuid s'utilise exactement de la même façon que le Guid:

ShortGuid shortGuidEmpty = ShortGuid.Empty; // Crée un ShortGuid vide
ShortGuid shortGuidA = ShortGuid.NewGuid(); // Crée un nouveau ShortGuid
Console.WriteLine("guidEmpty     : {0}", guidEmpty);
Console.WriteLine("shortGuidEmpty: {0}", shortGuidEmpty);
Console.WriteLine("shortGuidA    : {0}", shortGuidA);

Ce qui donne:

guidEmpty : 00000000-0000-0000-0000-000000000000
shortGuidEmpty: AAAAAAAAAAAAAAAAAAAAAA
shortGuidA    : 058fO04LSECNqoho_He67g

On peut convertir facilement le ShortGuid vers un Guid ou string:

Guid guidA = shortGuidA; // Convertit implicitement le ShortGuid en Guid
string stringA = shortGuidA; // Convertit implicitement le ShortGuid en String
Console.WriteLine("guidA         : {0}", guidA);

Ce qui donne:

guidA : 3b1f9fd3-0b4e-4048-8daa-8868fc77baee

Et inversement:

Guid guidB = Guid.NewGuid();
ShortGuid shortGuidB = guidB; // Convertit implicitement un Guid en ShortGuid
string stringC = "5Cqn2204Q0GTbI9dStW0fg";
ShortGuid shortGuidC = stringC; // Convertit implicitement une String en ShortGuid
Console.WriteLine("guidB         : {0}", guidB);

La comparaison avec le type Guid et String se fait naturellement:


Console.WriteLine("shortGuidA == shortGuidA: {0}", shortGuidA == shortGuidA);
Console.WriteLine("shortGuidA == shortGuidB: {0}", shortGuidA == shortGuidB);

Ce qui donne:

shortGuidA == guidEmpty: False
shortGuidA == shortGuidA: True
shortGuidA == shortGuidB: False

Voici le code de la classe ShortGuid:

/// <summary>
/// Represents a globally unique identifier (GUID) with a 
/// shorter string value. Sguid
/// </summary>
public struct ShortGuid : IComparable, IComparable<ShortGuid>, IComparable<Guid>, IComparable<string>
{
#region Static
/// <summary>
/// A read-only instance of the ShortGuid class whose value 
/// is guaranteed to be all zeroes. 
/// </summary>
public static readonly ShortGuid Empty = new ShortGuid(Guid.Empty);
#endregion
#region Fields
Guid _guid;
string _value;
#endregion
#region Contructors
/// <summary>
/// Creates a ShortGuid from a base64 encoded string
/// </summary>
/// <param name="value">The encoded guid as a 
/// base64 string</param>
public ShortGuid(string value)
{
_value = value;
_guid = Decode(value);
}
/// <summary>
/// Creates a ShortGuid from a Guid
/// </summary>
/// <param name="guid">The Guid to encode</param>
public ShortGuid(Guid guid)
{
_value = Encode(guid);
_guid = guid;
}
#endregion
#region Properties
/// <summary>
/// Gets/sets the underlying Guid
/// </summary>
public Guid Guid
{
get { return _guid; }
set
{
if (value != _guid)
{
_guid = value;
_value = Encode(value);
}
}
}
/// <summary>
/// Gets/sets the underlying base64 encoded string
/// </summary>
public string Value
{
get { return _value; }
set
{
if (value != _value)
{
_value = value;
_guid = Decode(value);
}
}
}
#endregion
#region ToString
/// <summary>
/// Returns the base64 encoded guid as a string
/// </summary>
/// <returns></returns>
public override string ToString()
{
return _value;
}
#endregion
#region Equals
/// <summary>
/// Returns a value indicating whether this instance and a 
/// specified Object represent the same type and value.
/// </summary>
/// <param name="obj">The object to compare</param>
/// <returns></returns>
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
/// <summary>
/// Returns the HashCode for underlying Guid.
/// </summary>
/// <returns></returns>
public override int GetHashCode()
{
return _guid.GetHashCode();
}
#endregion
#region NewGuid
/// <summary>
/// Initialises a new instance of the ShortGuid class
/// </summary>
/// <returns></returns>
public static ShortGuid NewGuid()
{
return new ShortGuid(Guid.NewGuid());
}
#endregion
#region Encode
/// <summary>
/// Creates a new instance of a Guid using the string value, 
/// then returns the base64 encoded version of the Guid.
/// </summary>
/// <param name="value">An actual Guid string (i.e. not a ShortGuid)</param>
/// <returns></returns>
public static string Encode(string value)
{
Guid guid = new Guid(value);
return Encode(guid);
}
/// <summary>
/// Encodes the given Guid as a base64 string that is 22 
/// characters long.
/// </summary>
/// <param name="guid">The Guid to encode</param>
/// <returns></returns>
public static string Encode(Guid guid)
{
string encoded = Convert.ToBase64String(guid.ToByteArray());
encoded = encoded
.Replace("/", "_")
.Replace("+", "-");
return encoded.Substring(0, 22);
}
#endregion
#region Decode
/// <summary>
/// Decodes the given base64 string
/// </summary>
/// <param name="value">The base64 encoded string of a Guid</param>
/// <returns>A new Guid</returns>
public static Guid Decode(string value)
{
value = value
.Replace("_", "/")
.Replace("-", "+");
byte[] buffer = Convert.FromBase64String(value + "==");
return new Guid(buffer);
}
#endregion
#region Operators
/// <summary>
/// Determines if both ShortGuids have the same underlying 
/// Guid value.
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public static bool operator ==(ShortGuid x, ShortGuid y)
{
if ((object)x == null) return (object)y == null;
return x._guid == y._guid;
}
/// <summary>
/// Determines if both ShortGuids do not have the 
/// same underlying Guid value.
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public static bool operator !=(ShortGuid x, ShortGuid y)
{
return !(x == y);
}
public static bool operator ==(ShortGuid x, Guid y)
{
if ((object)x == null) return (object)y == null;
return x._guid == y;
}
public static bool operator !=(ShortGuid x, Guid y)
{
return !(x == y);
}
public static bool operator ==(Guid x, ShortGuid y)
{
if ((object)x == null) return (object)y == null;
return x == y._guid;
}
public static bool operator !=(Guid x, ShortGuid y)
{
return !(x == y);
}
/// <summary>
/// Implicitly converts the ShortGuid to it's string equivilent
/// </summary>
/// <param name="shortGuid"></param>
/// <returns></returns>
public static implicit operator string(ShortGuid shortGuid)
{
return shortGuid._value;
}
/// <summary>
/// Implicitly converts the ShortGuid to it's Guid equivilent
/// </summary>
/// <param name="shortGuid"></param>
/// <returns></returns>
public static implicit operator Guid(ShortGuid shortGuid)
{
return shortGuid._guid;
}
/// <summary>
/// Implicitly converts the string to a ShortGuid
/// </summary>
/// <param name="shortGuid"></param>
/// <returns></returns>
public static implicit operator ShortGuid(string shortGuid)
{
return new ShortGuid(shortGuid);
}
/// <summary>
/// Implicitly converts the Guid to a ShortGuid 
/// </summary>
/// <param name="guid"></param>
/// <returns></returns>
public static implicit operator ShortGuid(Guid guid)
{
return new ShortGuid(guid);
}
#endregion
#region CompareTo
public int CompareTo(object other)
{
if (ReferenceEquals(other, null))
return 1;
if (other is ShortGuid)
return CompareTo((ShortGuid) other);
if (other is Guid)
return CompareTo((System.Guid) other);
if (other is string)
return CompareTo((string) other);
throw new ArgumentException("other");
}
public int CompareTo(ShortGuid other)
{
return _guid.CompareTo(other._guid);
}
public int CompareTo(Guid other)
{
return _guid.CompareTo(other);
}
public int CompareTo(string other)
{
return _value.CompareTo(other);
}
#endregion
}

Grégory Célet

ShortGuid.cs (8.73 kb)