diff --git a/HashifyNet/Algorithms/XxHash/XxHash3_Implementation.cs b/HashifyNet/Algorithms/XxHash/XxHash3_Implementation.cs
index 063a822..3d89cfe 100644
--- a/HashifyNet/Algorithms/XxHash/XxHash3_Implementation.cs
+++ b/HashifyNet/Algorithms/XxHash/XxHash3_Implementation.cs
@@ -34,6 +34,15 @@
namespace HashifyNet.Algorithms.XxHash3
{
+ ///
+ /// Provides an implementation of the XXH3 (XXHash3) hashing algorithm, supporting both 64-bit and 128-bit hash sizes.
+ ///
+ /// This class is designed to compute non-cryptographic hash values using the XXH3 algorithm. It
+ /// supports streaming input data and is configurable via an instance. The hash size is
+ /// fixed at either 64 or 128 bits, as specified in the configuration. This implementation is optimized for
+ /// performance and is suitable for scenarios requiring fast, high-quality non-cryptographic hashing, such as checksums
+ /// or hash-based data structures.
+ [HashAlgorithmImplementation(typeof(IXxHash3), typeof(XxHash3Config))]
internal class XxHash3_Implementation
: StreamableHashFunctionBase,
IXxHash3
@@ -103,3 +112,4 @@ protected override IHashValue FinalizeHashValueInternal(CancellationToken cancel
}
}
+
diff --git a/HashifyNet/Core/DataType/HashValue.cs b/HashifyNet/Core/DataType/HashValue.cs
index db3658e..89f8ec9 100644
--- a/HashifyNet/Core/DataType/HashValue.cs
+++ b/HashifyNet/Core/DataType/HashValue.cs
@@ -38,8 +38,12 @@
namespace HashifyNet.Core.Utilities
{
///
- /// Implementation of
+ /// Represents a hash value and its associated bit length.
///
+ /// This class provides a representation of a hash value as an immutable sequence of bytes, along with
+ /// its bit length. It includes methods to convert the hash value into various formats, such as Base64, hexadecimal,
+ /// and numeric types. The hash value is immutable and ensures that the provided bit length matches the actual length
+ /// of the hash in bits.
public class HashValue
: IHashValue
{
@@ -54,12 +58,12 @@ public class HashValue
public int BitLength { get; }
///
- /// Initializes a new instance of .
+ /// Creates a new instance of the class that is a representation of a hash value and its bit length computed by a hasher.
///
- /// The hash.
- /// Length of the hash, in bits.
- ///
- /// ;bitLength must be greater than or equal to 1.
+ /// The hash computed by a hasher.
+ /// The expected bit length of the given .
+ /// Thrown if the given hash is .
+ /// Thrown if the parameter is smaller than 1.
public HashValue(IEnumerable hash, int bitLength)
{
if (hash == null)
@@ -82,16 +86,6 @@ public HashValue(IEnumerable hash, int bitLength)
BitLength = bitLength;
}
- ///
- ///
- ///
- ///
- ///
- public string AsBase64String(Base64FormattingOptions formattingOptions = Base64FormattingOptions.None)
- {
- return Convert.ToBase64String(Hash.ToArray(), formattingOptions);
- }
-
///
///
///
@@ -106,223 +100,216 @@ public BigInteger AsBigInteger()
///
///
///
- [CLSCompliant(false)]
- public ulong AsUInt64()
+ public Guid AsGuid()
{
- byte[] data = AsByteArray();
- if (data.Length > 8)
+ if (BitLength > 128)
{
- throw new InvalidOperationException("Hash is too large to fit in a UInt64.");
+ throw new InvalidOperationException("Hash must be smaller than or equal to 16 bytes.");
}
- ulong result = 0;
- for (int i = 0; i < data.Length; i++)
- {
- result |= (ulong)data[i] << (8 * i);
- }
- return result;
- }
- ///
- ///
- ///
- ///
- ///
- public Guid AsGuid()
- {
byte[] data = AsByteArray();
- if (data.Length != 16)
+ if (data.Length < 16)
{
- throw new InvalidOperationException("Hash must be exactly 16 bytes to convert to a GUID.");
+ byte[] paddedData = new byte[16];
+ Array.Copy(data, paddedData, data.Length);
+ data = paddedData;
}
return new Guid(data);
}
+ #region Non-CLS-Compliant API
///
- ///
+ /// Gets the hash value as an unsigned 64-bit integer. If the bit length is greater than 64, an exception is thrown.
+ /// This API is not CLS-Compliant.
///
- ///
- ///
- public int AsInt32()
+ /// An unsigned 64-bit integer value.
+ [CLSCompliant(false)]
+ public ulong AsUInt64()
{
- byte[] data = AsByteArray();
- if (data.Length > 4)
- {
- throw new InvalidOperationException("Hash is too large to fit in an Int32.");
- }
- int result = 0;
- for (int i = 0; i < data.Length; i++)
- {
- result |= data[i] << (8 * i);
- }
- return result;
+ return (ulong)AsNumber64();
}
///
- ///
+ /// Gets the hash value as an unsigned 32-bit integer. If the bit length is greater than 32, an exception is thrown.
+ /// This API is not CLS-Compliant.
///
- ///
- ///
+ /// An unsigned 32-bit integer.
[CLSCompliant(false)]
public uint AsUInt32()
{
- byte[] data = AsByteArray();
- if (data.Length > 4)
- {
- throw new InvalidOperationException("Hash is too large to fit in a UInt32.");
- }
- uint result = 0;
- for (int i = 0; i < data.Length; i++)
- {
- result |= (uint)data[i] << (8 * i);
- }
- return result;
+ return (uint)AsNumber32();
}
+ ///
+ /// Gets the hash value as a unsigned 16-bit integer. If the bit length is greater than 16, an exception is thrown.
+ /// This API is not CLS-Compliant.
+ ///
+ /// An unsigned 16-bit integer.
+ [CLSCompliant(false)]
+ public ushort AsUInt16()
+ {
+ return (ushort)AsNumber16();
+ }
+ #endregion
+
///
///
///
///
- ///
- public long AsInt64()
+ public int AsInt32()
{
- byte[] data = AsByteArray();
- if (data.Length > 8)
- {
- throw new InvalidOperationException("Hash is too large to fit in an Int64.");
- }
- long result = 0;
- for (int i = 0; i < data.Length; i++)
- {
- result |= (long)data[i] << (8 * i);
- }
- return result;
+ return AsNumber32();
}
///
///
///
///
- ///
- public short AsInt16()
+ public long AsInt64()
{
- byte[] data = AsByteArray();
- if (data.Length > 2)
- {
- throw new InvalidOperationException("Hash is too large to fit in an Int16.");
- }
- short result = 0;
- for (int i = 0; i < data.Length; i++)
- {
- result |= (short)(data[i] << (8 * i));
- }
- return result;
+ return AsNumber64();
}
///
///
///
///
- ///
- [CLSCompliant(false)]
- public ushort AsUInt16()
+ public short AsInt16()
{
- byte[] data = AsByteArray();
- if (data.Length > 2)
- {
- throw new InvalidOperationException("Hash is too large to fit in a UInt16.");
- }
- ushort result = 0;
- for (int i = 0; i < data.Length; i++)
- {
- result |= (ushort)(data[i] << (8 * i));
- }
- return result;
+ return AsNumber16();
}
///
///
///
///
- ///
public char AsChar()
{
- byte[] data = AsByteArray();
- if (data.Length > 2)
- {
- throw new InvalidOperationException("Hash is too large to fit in a Char.");
- }
- char result = (char)0;
- for (int i = 0; i < data.Length; i++)
- {
- result |= (char)(data[i] << (8 * i));
- }
- return result;
+ return (char)AsNumber16();
}
///
///
///
///
- ///
public float AsSingle()
{
- byte[] data = AsByteArray();
- if (data.Length != 4)
+ int l = AsNumber32();
+ unsafe
{
- throw new InvalidOperationException("Hash must be exactly 4 bytes to convert to a Single.");
+ return *(float*)&l;
}
- return BitConverter.ToSingle(data, 0);
}
///
///
///
///
- ///
public double AsDouble()
{
- byte[] data = AsByteArray();
- if (data.Length != 8)
+ long l = AsNumber64();
+ unsafe
{
- throw new InvalidOperationException("Hash must be exactly 8 bytes to convert to a Double.");
+ return *(double*)&l;
}
- return BitConverter.ToDouble(data, 0);
}
///
///
///
///
- ///
public decimal AsDecimal()
{
+ return AsNumber128_96();
+ }
+
+ private decimal AsNumber128_96()
+ {
+ if (BitLength < 1)
+ throw new ArgumentException("Bit Length cannot be smaller than 1.");
+
+ if (BitLength > 96)
+ throw new NotSupportedException("Bit Length greater than 96 is not supported.");
+
+ byte[] data = AsByteArray();
+
+ byte[] dataPadded = new byte[12];
+ Array.Copy(data, dataPadded, data.Length);
+
+ int lo = (int)Endianness.ToUInt32LittleEndian(dataPadded, 0);
+ int mid = (int)Endianness.ToUInt32LittleEndian(dataPadded, 4);
+ int hi = (int)Endianness.ToUInt32LittleEndian(dataPadded, 8);
+ return new decimal(lo, mid, hi, false, 0);
+ }
+
+ private long AsNumber64()
+ {
+ if (BitLength < 1)
+ throw new ArgumentException("Bit Length cannot be smaller than 1.");
+
+ if (BitLength > 64)
+ throw new NotSupportedException("Bit Length greater than 64 is not supported.");
+
byte[] data = AsByteArray();
- if (data.Length != 16)
+
+ long num = 0;
+ for (int i = 0; i < data.Length; ++i)
+ {
+ num |= (long)data[i] << (8 * i);
+ }
+
+ return num;
+ }
+
+ private int AsNumber32()
+ {
+ if (BitLength > 32)
{
- throw new InvalidOperationException("Hash must be exactly 16 bytes to convert to a Decimal.");
+ throw new NotSupportedException("Bit Length greater than 32 is not supported.");
}
- int[] bits = new int[4];
- for (int i = 0; i < 4; i++)
+
+ return (int)AsNumber64();
+ }
+
+ private short AsNumber16()
+ {
+ if (BitLength > 16)
{
- bits[i] = BitConverter.ToInt32(data, i * 4);
+ throw new NotSupportedException("Bit Length greater than 16 is not supported.");
}
- return new decimal(bits);
+
+ return (short)AsNumber64();
}
///
///
///
///
- ///
public DateTime AsDateTime()
{
- byte[] data = AsByteArray();
- if (data.Length != 8)
+ long ticks = AsNumber64();
+ if (ticks < 0)
+ {
+ ticks &= long.MaxValue;
+ }
+
+ if (BitLength < 64)
{
- throw new InvalidOperationException("Hash must be exactly 8 bytes to convert to a DateTime.");
+ double maxHashValue = (double)(1L << BitLength);
+ ticks = (long)(ticks / maxHashValue * DateTime.MaxValue.Ticks);
}
- long ticks = BitConverter.ToInt64(data, 0);
+
+ if (ticks < DateTime.MinValue.Ticks)
+ {
+ ticks = DateTime.MinValue.Ticks;
+ }
+
+ if (ticks > DateTime.MaxValue.Ticks)
+ {
+ ticks = DateTime.MaxValue.Ticks;
+ }
+
return new DateTime(ticks);
}
@@ -330,15 +317,30 @@ public DateTime AsDateTime()
///
///
///
- ///
public DateTimeOffset AsDateTimeOffset()
{
- byte[] data = AsByteArray();
- if (data.Length != 8)
+ long ticks = AsNumber64();
+ if (ticks < 0)
{
- throw new InvalidOperationException("Hash must be exactly 8 bytes to convert to a DateTimeOffset.");
+ ticks &= long.MaxValue;
}
- long ticks = BitConverter.ToInt64(data, 0);
+
+ if (BitLength < 64)
+ {
+ double maxHashValue = (double)(1L << BitLength);
+ ticks = (long)(ticks / maxHashValue * DateTimeOffset.MaxValue.Ticks);
+ }
+
+ if (ticks < DateTimeOffset.MinValue.Ticks)
+ {
+ ticks = DateTimeOffset.MinValue.Ticks;
+ }
+
+ if (ticks > DateTimeOffset.MaxValue.Ticks)
+ {
+ ticks = DateTimeOffset.MaxValue.Ticks;
+ }
+
return new DateTimeOffset(ticks, TimeSpan.Zero);
}
@@ -346,15 +348,30 @@ public DateTimeOffset AsDateTimeOffset()
///
///
///
- ///
public TimeSpan AsTimeSpan()
{
- byte[] data = AsByteArray();
- if (data.Length != 8)
+ long ticks = AsNumber64();
+ if (ticks < 0)
{
- throw new InvalidOperationException("Hash must be exactly 8 bytes to convert to a TimeSpan.");
+ ticks &= long.MaxValue;
}
- long ticks = BitConverter.ToInt64(data, 0);
+
+ if (BitLength < 64)
+ {
+ double maxHashValue = (double)(1L << BitLength);
+ ticks = (long)(ticks / maxHashValue * TimeSpan.MaxValue.Ticks);
+ }
+
+ if (ticks < TimeSpan.MinValue.Ticks)
+ {
+ ticks = TimeSpan.MinValue.Ticks;
+ }
+
+ if (ticks > TimeSpan.MaxValue.Ticks)
+ {
+ ticks = TimeSpan.MaxValue.Ticks;
+ }
+
return new TimeSpan(ticks);
}
@@ -377,14 +394,17 @@ public string AsBinaryString()
///
///
///
- public string AsBase85()
+ public string AsBase85String()
{
+ if (BitLength < 1)
+ return "";
+
const string Base85Alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~";
byte[] data = AsByteArray();
- if (data.Length == 0) return "";
var builder = new StringBuilder();
int value = 0;
int count = 0;
+
foreach (byte b in data)
{
value = (value << 8) | b;
@@ -410,12 +430,25 @@ public string AsBase85()
return builder.ToString();
}
+ ///
+ ///
+ ///
+ ///
+ ///
+ public string AsBase64String(Base64FormattingOptions formattingOptions = Base64FormattingOptions.None)
+ {
+ return Convert.ToBase64String(Hash.ToArray(), formattingOptions);
+ }
+
///
///
///
///
- public string AsBase58()
+ public string AsBase58String()
{
+ if (BitLength < 1)
+ return "";
+
const string Base58Alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
byte[] data = AsByteArray();
@@ -442,13 +475,14 @@ public string AsBase58()
///
///
///
- public string AsBase32()
+ public string AsBase32String()
{
+ if (BitLength < 1)
+ return "";
+
const string Base32Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
byte[] data = AsByteArray();
- if (data.Length == 0) return "";
-
var builder = new StringBuilder();
int bitsRead = 0;
int buffer = 0;
@@ -481,9 +515,31 @@ public string AsBase32()
///
///
///
- ///
+ ///
+ public string AsHexString() => AsHexString(false);
+
+ ///
///
- ///
+ ///
+ ///
+ ///
+ public string AsHexString(bool uppercase)
+ {
+ var stringBuilder = new StringBuilder(Hash.Length);
+ var formatString = uppercase ? "X2" : "x2";
+
+ foreach (var byteValue in Hash)
+ {
+ stringBuilder.Append(byteValue.ToString(formatString));
+ }
+
+ return stringBuilder.ToString();
+ }
+
+ ///
+ ///
+ ///
+ ///
public BitArray AsBitArray()
{
return new BitArray(Hash.ToArray())
@@ -504,37 +560,26 @@ public byte[] AsByteArray()
///
///
///
- ///
- ///
- ///
- public string AsHexString() => AsHexString(false);
-
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public string AsHexString(bool uppercase)
+ ///
+ ///
+ ///
+ public virtual IHashValue Coerce(int bitLength)
{
- var stringBuilder = new StringBuilder(Hash.Length);
- var formatString = uppercase ? "X2" : "x2";
-
- foreach (var byteValue in Hash)
+ if (bitLength < 1)
{
- stringBuilder.Append(byteValue.ToString(formatString));
+ throw new ArgumentOutOfRangeException(nameof(bitLength), $"{nameof(bitLength)} must be greater than or equal to 1.");
}
- return stringBuilder.ToString();
+ return new HashValue(ArrayHelpers.CoerceToArray(Hash.ToArray(), bitLength), bitLength);
}
///
- /// Returns a hash code for this instance.
+ /// Computes a hash code for the current object.
///
- ///
- /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
- ///
+ /// The hash code is calculated based on the values of the property and the
+ /// elements of the collection. This ensures that objects with the same data produce the same hash
+ /// code.
+ /// An integer representing the hash code for the current object.
public override int GetHashCode()
{
unchecked
@@ -553,24 +598,24 @@ public override int GetHashCode()
}
///
- /// Determines whether the specified , is equal to this instance.
+ /// Determines whether the specified object is equal to the current object.
///
- /// The to compare with this instance.
- ///
- /// true if the specified is equal to this instance; otherwise, false.
- ///
+ /// The object to compare with the current object. This can be .
+ /// if the specified object is an and is equal to the current object;
+ /// otherwise, .
public override bool Equals(object obj)
{
return Equals(obj as IHashValue);
}
///
- /// Indicates whether the current object is equal to another object of the same type.
+ /// Determines whether the current hash value is equal to the specified instance.
///
- /// An object to compare with this object.
- ///
- /// true if the current object is equal to the parameter; otherwise, false.
- ///
+ /// This method performs a fixed-time comparison of the hash values to mitigate timing attacks. The
+ /// comparison takes into account the bit length of the hash and the hash data itself.
+ /// The instance to compare with the current instance.
+ /// if the current hash value is equal to ; otherwise, .
public bool Equals(IHashValue other)
{
if (other == null || other.BitLength != BitLength)
@@ -586,10 +631,19 @@ public bool Equals(IHashValue other)
}
///
- ///
+ /// Compares the current hash value to another hash value and determines their relative order.
///
- ///
- ///
+ /// The comparison is performed based on the bit length of the hash values and their byte-by-byte
+ /// content. If the bit lengths differ, the hash with the smaller bit length is considered less. If the bit lengths
+ /// are equal, the comparison proceeds byte by byte, and any remaining bits in the final byte are compared using a bit
+ /// mask.
+ /// The hash value to compare with the current instance. Cannot be .
+ /// A signed integer that indicates the relative order of the hash values:
+ /// - Less than zero if the current instance is less than .
- Zero if the current instance is equal to .
- Greater than zero if the current instance is greater than
+ /// .
+ /// Thrown if is .
public int CompareTo(IHashValue other)
{
_ = other ?? throw new ArgumentNullException(nameof(other));
@@ -627,21 +681,5 @@ public int CompareTo(IHashValue other)
return 0;
}
-
- ///
- ///
- ///
- ///
- ///
- public virtual IHashValue Coerce(int bitLength)
- {
- if (bitLength < 1)
- {
- throw new ArgumentOutOfRangeException(nameof(bitLength), $"{nameof(bitLength)} must be greater than or equal to 1.");
- }
-
- return new HashValue(ArrayHelpers.CoerceToArray(Hash.ToArray(), bitLength), bitLength);
- }
}
}
-
diff --git a/HashifyNet/Core/DataType/IHashValue.cs b/HashifyNet/Core/DataType/IHashValue.cs
index a0dacba..91cfd56 100644
--- a/HashifyNet/Core/DataType/IHashValue.cs
+++ b/HashifyNet/Core/DataType/IHashValue.cs
@@ -41,208 +41,150 @@ public interface IHashValue
: IEquatable, IComparable
{
///
- /// Gets the length of the hash value in bits.
+ /// Gets the length of the hash in bits.
///
- ///
- /// The length of the hash value in bits.
- ///
int BitLength { get; }
///
- /// Gets resulting byte array.
+ /// Gets the hash value as an immutable array of bytes.
///
- ///
- /// The hash value.
- ///
- ///
- /// Implementations should coerce the input hash value to be size in bits.
- ///
ImmutableArray Hash { get; }
///
- /// Converts the hash value to a bit array.
+ /// Gets the hash value as a . If the bit length is greater than 128, an exception is thrown.
///
- /// A instance to represent this hash value.
- BitArray AsBitArray();
+ /// A Guid representation of the underlying hash value.
+ /// Thrown if is greater than 128.
+ Guid AsGuid();
///
- /// Converts the immutable array to a byte array representation.
+ /// Gets the hash value as a .
///
- /// A byte array that represents the current immutable array.
- byte[] AsByteArray();
+ /// The created instance.
+ BigInteger AsBigInteger();
///
- /// Converts the hash value to a hexadecimal string.
+ /// Gets the hash value as a signed 32-bit integer. If the bit length is greater than 32, an exception is thrown.
///
- /// A hex string representing this hash value.
- string AsHexString();
+ /// A signed 32-bit integer.
+ int AsInt32();
///
- /// Converts the hash value to a hexadecimal string.
+ /// Gets the hash value as a signed 64-bit integer. If the bit length is greater than 64, an exception is thrown.
///
- /// true if the result should use uppercase hex values; otherwise false.
- /// A hex string representing this hash value.
- string AsHexString(bool uppercase);
+ /// A signed 64-bit integer.
+ long AsInt64();
///
- /// Converts the hash value to a the base64 string.
+ /// Gets the hash value as a signed 16-bit integer. If the bit length is greater than 16, an exception is thrown.
///
- /// Formatting options for the generated base64 string.
- /// A base64 string representing this hash value.
- string AsBase64String(Base64FormattingOptions formattingOptions = Base64FormattingOptions.None);
+ /// A signed 16-bit integer.
+ short AsInt16();
///
- /// Converts the hash value to a representation with the specified bit length.
+ /// Gets the hash value as a Unicode character. If the bit length is greater than 16, an exception is thrown.
///
- /// This method allows the caller to adjust the bit length of the hash value to meet specific
- /// requirements. The resulting hash value may be truncated or padded, depending on the specified bit
- /// length.
- /// The desired bit length of the resulting hash value. Must be a positive integer.
- /// An instance representing the hash value with the specified bit length.
- IHashValue Coerce(int bitLength);
+ /// A unicode character.
+ char AsChar();
///
- /// Converts the current hash to its equivalent representation.
+ /// Gets the hash value as a single-precision floating point number. If the bit length is greater than 32, an exception is thrown.
///
- /// This method uses the byte array representation of the hash to construct the .
- /// A that represents the current hash.
- BigInteger AsBigInteger();
+ /// A single-precision floating point number.
+ float AsSingle();
///
- /// Converts the hash value to a .
+ /// Gets the hash value as a double-precision floating point number. If the bit length is greater than 64, an exception is thrown.
///
- /// The hash must be exactly 16 bytes in length to be converted to a . If the hash
- /// length is not 16 bytes, an exception is thrown.
- /// A representation of the hash value.
- /// Thrown if the hash is not exactly 16 bytes in length.
- Guid AsGuid();
+ /// A double-precision floating point number.
+ double AsDouble();
///
- /// Converts the hash value to a 32-bit integer representation.
+ /// Gets the hash value as a decimal number. If the bit length is greater than 96, an exception is thrown.
///
- /// This method interprets the hash value as a little-endian byte array and converts it to an . If the hash value exceeds 4 bytes, an exception is thrown.
- /// A 32-bit integer representation of the hash value.
- /// Thrown if the hash value exceeds 4 bytes in length.
- int AsInt32();
+ /// A decimal number.
+ decimal AsDecimal();
///
- /// Converts the hash value to a 64-bit signed integer.
+ /// Gets the hash value as a . The hash value is interpreted as the number of ticks (100-nanosecond intervals) since 12:00:00 midnight, January 1, 0001.
///
- /// This method interprets the hash value as a little-endian byte array and converts it to a 64-bit
- /// signed integer. If the hash value exceeds 8 bytes, an exception is thrown.
- /// A 64-bit signed integer representation of the hash value.
- /// Thrown if the hash value is larger than 8 bytes.
- long AsInt64();
+ /// The generated instance.
+ DateTime AsDateTime();
///
- /// Converts the hash value to a 16-bit signed integer.
+ /// Gets the hash value as a . The hash value is interpreted as the number of ticks (100-nanosecond intervals) since 12:00:00 midnight, January 1, 0001.
///
- /// This method interprets the hash value as a little-endian byte array and converts it to a 16-bit
- /// signed integer. If the hash value exceeds 2 bytes in length, an exception is thrown.
- /// A 16-bit signed integer representation of the hash value.
- /// Thrown if the hash value exceeds 2 bytes in length.
- short AsInt16();
+ /// The generated instance.
+ DateTimeOffset AsDateTimeOffset();
///
- /// Converts the hash value to a representation.
+ /// Gets the hash value as a . The hash value is interpreted as the number of ticks (100-nanosecond intervals).
///
- /// This method interprets the hash as a sequence of bytes and converts it into a .
- /// If the hash contains more than two bytes, an exception is thrown.
- /// A representation of the hash value.
- /// Thrown if the hash contains more than two bytes, as it cannot be represented as a .
- char AsChar();
+ /// The generated instance.
+ TimeSpan AsTimeSpan();
///
- /// Converts the hash value to a single-precision floating-point number.
+ /// Gets the hash value as a binary string. Each byte is represented by 8 bits, with leading zeros if necessary.
///
- /// The hash must be exactly 4 bytes in length to perform the conversion. If the hash length is not 4
- /// bytes, an is thrown.
- /// A representation of the hash value.
- /// Thrown if the hash is not exactly 4 bytes in length.
- float AsSingle();
+ /// The generated binary string.
+ string AsBinaryString();
///
- /// Converts the hash value to a representation.
+ /// Gets the hash value as a Base85-encoded string. If the bit length is not a multiple of 8, the last byte is padded with zeros.
///
- /// The hash must be exactly 8 bytes in length to perform the conversion. If the hash length is not
- /// 8 bytes, an exception is thrown.
- /// A representation of the hash value.
- /// Thrown if the hash is not exactly 8 bytes in length.
- double AsDouble();
+ /// The generated base85 string.
+ string AsBase85String();
///
- /// Converts the hash value to a representation.
+ /// Gets the hash value as a Base64-encoded string. If the bit length is not a multiple of 8, the last byte is padded with zeros.
///
- /// The hash must be exactly 16 bytes in length to be converted to a . If the
- /// hash length is not 16 bytes, an exception is thrown.
- /// A representation of the hash value.
- /// Thrown if the hash is not exactly 16 bytes in length.
- decimal AsDecimal();
+ /// The formatting options for generating base64 encoded string.
+ /// The generated base64 encoded string.
+ string AsBase64String(Base64FormattingOptions formattingOptions = Base64FormattingOptions.None);
///
- /// Converts the hash value to a instance.
+ /// Gets the hash value as a Base58-encoded string. If the bit length is not a multiple of 8, the last byte is padded with zeros.
///
- /// The hash must be exactly 8 bytes long to represent a valid . If the hash
- /// length is not 8 bytes, an exception is thrown.
- /// A instance created from the hash value.
- /// Thrown if the hash is not exactly 8 bytes long.
- DateTime AsDateTime();
+ /// The generated base58 string.
+ string AsBase58String();
///
- /// Converts the hash value to a .
+ /// Gets the hash value as a Base32-encoded string. If the bit length is not a multiple of 8, the last byte is padded with zeros.
///
- /// The hash must be exactly 8 bytes long to perform the conversion. The resulting is created with a UTC offset of .
- /// A representation of the hash value.
- /// Thrown if the hash is not exactly 8 bytes long.
- DateTimeOffset AsDateTimeOffset();
+ /// The generated base32 string.
+ string AsBase32String();
///
- /// Converts the hash value to a instance.
+ /// Gets the hash value as a hexadecimal string, using lowercase letters for 'a' to 'f'.
///
- /// The hash value must be exactly 8 bytes long to be converted to a . If the
- /// hash length is not 8 bytes, an exception is thrown.
- /// A representing the hash value.
- /// Thrown if the hash value is not exactly 8 bytes long.
- TimeSpan AsTimeSpan();
+ /// The hexadecimal string.
+ string AsHexString();
///
- /// Converts the current hash to its binary string representation.
+ /// Gets the hash value as a hexadecimal string.
///
- /// This method generates a binary string where each byte of the hash is represented as an
- /// 8-character binary value, padded with leading zeros if necessary. The resulting string concatenates the binary
- /// representations of all bytes in sequence.
- /// A string containing the binary representation of the hash.
- string AsBinaryString();
+ /// Indicating to use uppercase letters.
+ /// The hexadecimal string.
+ string AsHexString(bool uppercase);
///
- /// Encodes the current hash as a Base85-encoded string.
+ /// Gets the hash value as a .
///
- /// This method converts the hash's data, represented as a byte array, into a Base85-encoded string
- /// using the ASCII85 encoding scheme. Base85 encoding is a compact representation of binary data that uses a set of
- /// 85 printable ASCII characters.
- /// A Base85-encoded string representation of the hash's data. Returns an empty string if the byte array is empty.
- string AsBase85();
+ /// The created instance.
+ BitArray AsBitArray();
///
- /// Converts the current hash to its Base58-encoded string representation.
+ /// Gets the hash value as a modifiable byte array.
///
- /// This method uses the Base58 encoding scheme, which is commonly used in applications such as
- /// cryptocurrency addresses. The encoding excludes visually ambiguous characters such as '0', 'O', 'I', and
- /// 'l'.
- /// A Base58-encoded string representation of the current hash.
- string AsBase58();
+ /// The modifiable byte array.
+ byte[] AsByteArray();
///
- /// Converts the current hash to a Base32-encoded string representation.
+ /// Converts the current hash value to a new representation with the specified bit length.
///
- /// The Base32 encoding uses the alphabet "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567" and appends padding
- /// characters ('=') to ensure the output length is a multiple of 8. This method processes the hash's data as a
- /// byte array and encodes it into Base32 format.
- /// A Base32-encoded string representation of the hash's data. Returns an empty string if the hash's data is
- /// empty.
- string AsBase32();
+ /// The desired bit length of the resulting hash value. Must be greater than or equal to 1.
+ /// An instance representing the hash value coerced to the specified bit length.
+ /// Thrown if is less than 1.
+ IHashValue Coerce(int bitLength);
}
}
diff --git a/HashifyNet/HashifyNet.csproj b/HashifyNet/HashifyNet.csproj
index f1e36f7..8dc47a4 100644
--- a/HashifyNet/HashifyNet.csproj
+++ b/HashifyNet/HashifyNet.csproj
@@ -1,4 +1,4 @@
-
+
netstandard2.0;net8.0
@@ -67,8 +67,11 @@
-
-
+
+
+
+
+
@@ -91,9 +94,8 @@
Deskasoft International
HashifyNET
Copyright © Deskasoft International
- 5.0.0
+ 5.0.1
hashing;hash;algorithms;security;crypto;non-crypto;CLS-compliant;VB.NET;F#
- LICENSE
True
False
False
@@ -106,6 +108,8 @@
logo.png
..\HashifyNET.publickey
$(MSBuildProjectName.Replace("Net", "NET"))
+ $(Company)
+ MIT
diff --git a/README.md b/README.md
index 6172176..61aa9b4 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
HashifyNET
=================
-HashifyNET is a CLS-Compliant .NET library designed to offer a common interface for a wide range of [cryptographic](https://en.wikipedia.org/wiki/List_of_hash_functions#Keyed_cryptographic_hash_functions) and [non-cryptographic](https://en.wikipedia.org/wiki/List_of_hash_functions#Non-cryptographic_hash_functions) hashing algorithms, while also providing built-in implementations of numerous well-known hash functions.
+HashifyNET is a CLS-Compliant, platform-independent .NET library designed to offer a common interface for a wide range of [cryptographic](https://en.wikipedia.org/wiki/List_of_hash_functions#Keyed_cryptographic_hash_functions) and [non-cryptographic](https://en.wikipedia.org/wiki/List_of_hash_functions#Non-cryptographic_hash_functions) hashing algorithms, while also providing built-in implementations of numerous well-known hash functions.
All functionality of the library is tested using [xUnit](https://github.com/xunit/xunit). A primary requirement for each release is 100% code coverage by these tests.
All code within the library is commented using Visual Studio-compatible XML comments.
@@ -238,3 +238,4 @@ License
HashifyNET is released under the terms of the MIT license. See [LICENSE](https://github.com/deskasoft/HashifyNET/blob/master/LICENSE) for more information or see http://opensource.org/licenses/MIT.
+