using System.Text; namespace System.Security.Cryptography { /// /// The HashString structure can be used to transform a list of bytes with a minimum length of 16 into a /// or . /// public readonly struct HashString : IEquatable, IComparable, IEquatable, IFormattable { private readonly byte[] hash; /// /// A read-only instance of type whose value is all zero. /// public readonly static HashString Empty = new HashString(new byte[16]); /// /// Initializes a object using a list of bytes with a minimum length of 16. /// /// /// /// public HashString(byte[] hash) { if (hash is null) throw new ArgumentNullException("The hash parameter cannot be null."); else if (hash.Length < 16) throw new ArgumentException("The hash parameter cannot have a length shorter than 16."); this.hash = hash; } /// /// Indicates whether this instance and a specified object are equal. /// /// The to compare with the current instance. /// true if obj and this instance are the same type and represent the same value; otherwise, false. public override bool Equals(object obj) => (obj is HashString hs && Equals(hs)) || (obj is string stg && Equals(stg)); /// /// Returns the hash code for this instance. /// /// A 32-bit signed integer that is the hash code for this instance. public override int GetHashCode() { int res = 0; foreach (byte item in hash) res ^= item; return res; } /// /// Indicates whether the current object is equal to another object of the same type. /// /// An object to compare with this object. /// true if the current object is equal to the other parameter; otherwise, false. public bool Equals(HashString other) => ((Guid)this) == ((Guid)other); /// /// Indicates whether the current object is equal to another object of the same type. /// /// An object to compare with this object. /// Use .ToString() or convert a list of bytes to a using a or similar. /// /// true if the current object is equal to the other parameter; otherwise, false. public bool Equals(string other) { StringBuilder builder = new StringBuilder(); foreach (byte item in hash) builder.Append(item); return other == builder.ToString() || ToString() == other; } /// /// Returns a string representation of the value of this instance in registry format. /// /// The value of this , formatted by using the "D" format specifier as /// follows: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx where the value of the GUID is /// represented as a series of lowercase hexadecimal digits in groups of 8, 4, 4, /// 4, and 12 digits and separated by hyphens. An example of a return value is "382c74c3-721d-4f34-80e5-57657b6cbc27". /// To convert the hexadecimal digits from a through f to uppercase, call the System.String.ToUpper /// method on the returned string. /// public override string ToString() => ((Guid)this).ToString(); /// /// Returns a string representation of the value of this instance, according to the provided format specifier. /// /// A single format specifier that indicates how to format the value of this . /// The format parameter can be "N", "D", "B", "P", or "X". If format is null or /// an empty string (""), "D" is used. /// /// The value of format is not null, an empty string (""), "N", "D", "B", "P", or "X". /// The value of this , represented as a series of lowercase hexadecimal /// digits in the specified format. /// public string ToString(string format) => ((Guid)this).ToString(format); /// /// Returns a string representation of the value of this instance of the /// class, according to the provided format specifier and culture-specific format /// information. /// /// A single format specifier that indicates how to format the value of this . /// The format parameter can be "N", "D", "B", "P", or "X". If format is null or /// an empty string (""), "D" is used. /// /// (Reserved) An object that supplies culture-specific formatting information. /// The value of this , represented as a series of lowercase hexadecimal /// digits in the specified format. /// public string ToString(string format, IFormatProvider formatProvider) => ((Guid)this).ToString(format, formatProvider); /// /// Compares this instance to a specified object and returns an indication /// of their relative values. /// /// An object to compare to this instance. /// A signed number indicating the relative values of this instance and value. Return /// value Description A negative integer This instance is less than value. Zero This /// instance is equal to value. A positive integer This instance is greater than /// value. public int CompareTo(HashString other) => ((Guid)this).CompareTo((Guid)other); /// /// Implicit conversion from to type. /// public static implicit operator string(HashString hash) => hash.ToString(); /// /// Explicit conversion from object to . /// public static explicit operator Guid(HashString hash) { byte[] h16 = new byte[16]; for (long I = 0, J = 0; I < hash.hash.LongLength; I++) { h16[J++] ^= hash.hash[I]; J = J >= 16 ? 0 : J; } return new Guid(h16); } } }