GxHash.128bits.Overloads 1.3.0

dotnet add package GxHash.128bits.Overloads --version 1.3.0
                    
NuGet\Install-Package GxHash.128bits.Overloads -Version 1.3.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="GxHash.128bits.Overloads" Version="1.3.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="GxHash.128bits.Overloads" Version="1.3.0" />
                    
Directory.Packages.props
<PackageReference Include="GxHash.128bits.Overloads" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add GxHash.128bits.Overloads --version 1.3.0
                    
#r "nuget: GxHash.128bits.Overloads, 1.3.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package GxHash.128bits.Overloads@1.3.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=GxHash.128bits.Overloads&version=1.3.0
                    
Install as a Cake Addin
#tool nuget:?package=GxHash.128bits.Overloads&version=1.3.0
                    
Install as a Cake Tool

GxHash.128bits.Overloads

GxHash.128bits.Overloads is an extension library for GxHash that provides a comprehensive set of overloads to compute 128-bit hashes on various data types: files, string, ReadOnlySpan(T), Span(T), T[], List(T), Stream, T.

Features

  • Compute 128-bit hash (UInt128) for:
    • File contents (string filePath)
    • string values
    • Span<byte> and ReadOnlySpan<byte>
    • Generic Span<T> and ReadOnlySpan<T> where T : unmanaged
    • Arrays T[] where T : unmanaged
    • Lists List<T> where T : unmanaged
    • Stream instances
  • Optional seeding for all methods

Installation

Install via NuGet:

Package Download
GxHash.128bits.Overloads NuGet NuGet
dotnet add package GxHash.128bits.Overloads

Quick Start

using GxHash.Overloads;

class Program
{
    static void Main()
    {
        // Hash via extension methods
        {
            // Hash a string
            UInt128 hash1 = "Hello, World!".Hash128();
            Console.WriteLine($"String hash: {hash1}");

            // Hash with custom seed
            UInt128 seed = new UInt128(1234567890, 9876543210);
            UInt128 hash2 = "Hello, World!".Hash128(seed);
            Console.WriteLine($"String hash with seed: {hash2}");

            // Hash a file
            string path = "data.bin";
            UInt128 fileHash = File.Hash128(path); // Only for .NET 10 and higher
            Console.WriteLine($"File hash: {fileHash}");

            // Hash a byte span
            byte[] data = [1, 2, 3, 4];
            UInt128 spanHash = data.Hash128();
            Console.WriteLine($"Span hash: {spanHash}");

            // Hash a stream
            using var stream = File.OpenRead(path);
            UInt128 streamHash = stream.Hash128(seed: seed);
            Console.WriteLine($"Stream hash: {streamHash}");

            // Hash of a simple type
            long longValue = 1234567890;
            Console.WriteLine($"Long hash: {longValue.Hash128()}");

            // Hash of a struct
            ExampleStruct structValue = new ExampleStruct();
            Console.WriteLine($"Long hash: {structValue.Hash128()}");
        }



        // Hash via direct call
        {
            // Hash a string
            UInt128 hash1 = GxHash128.Hash128("Hello, World!");
            Console.WriteLine($"String hash: {hash1}");

            // Hash with custom seed
            UInt128 seed = new UInt128(1234567890, 9876543210);
            UInt128 hash2 = GxHash128.Hash128("Hello, World!", seed);
            Console.WriteLine($"String hash with seed: {hash2}");

            // Hash a file
            string path = "data.bin";
            UInt128 fileHash = GxHash128.FileContentHash128(path);
            Console.WriteLine($"File hash: {fileHash}");

            // Hash a byte span
            byte[] data = [1, 2, 3, 4];
            UInt128 spanHash = GxHash128.Hash128((ReadOnlySpan<byte>) data);
            Console.WriteLine($"Span hash: {spanHash}");

            // Hash a stream
            using var stream = File.OpenRead(path);
            UInt128 streamHash = GxHash128.Hash128(stream, seed);
            Console.WriteLine($"Stream hash: {streamHash}");

            // Hash of a simple type
            long longValue = 1234567890;
            UInt128 longHash = GxHash128.Hash128(longValue);
            Console.WriteLine($"Long hash: {longHash}");

            // Hash of a struct
            ExampleStruct structValue = new ExampleStruct();
            UInt128 structHash = GxHash128.Hash128(structValue);
            Console.WriteLine($"Struct hash: {structHash}");
        }
    }
}

struct ExampleStruct
{
    public int intValue;
    public long longValue;
}

API Reference

namespace GxHash.Overloads;

public static class GxHash128
{
    // File overloads
    public static UInt128 FileContentHash128(string filePath, int bufferSize = 4096, UInt128 seed = default, FileShare share = FileShare.Read)
    public static async Task<UInt128> FileContentHash128Async(string filePath, int bufferSize = 4096, UInt128 seed = default, FileShare share = FileShare.Read, CancellationToken cancellationToken = default)

    // String overloads
    public static UInt128 Hash128(string? str, UInt128 seed = default)

    // Byte ReadOnlySpan overloads
    public static UInt128 Hash128(ReadOnlySpan<byte> buffer, UInt128 seed = default)
    public static UInt128 Hash128<T>(ReadOnlySpan<T> buffer, UInt128 seed = default) where T : unmanaged

    // Byte Span overloads
    public static UInt128 Hash128(Span<byte> buffer, UInt128 seed = default)
    public static UInt128 Hash128<T>(Span<T> buffer, UInt128 seed = default) where T : unmanaged

    // Array overloads
    public static UInt128 Hash128<T>(T[]? array, UInt128 seed = default) where T : unmanaged

    // List overloads
    public static UInt128 Hash128<T>(List<T>? list, UInt128 seed = default) where T : unmanaged

    // Stream overload
    public static UInt128 Hash128(Stream stream, int bufferSize = 4096, UInt128 seed = default)
    public static async Task<UInt128> Hash128Async(Stream stream, int bufferSize = 4096, UInt128 seed = default, CancellationToken cancellationToken = default)

    // T overloads
    public static unsafe UInt128 Hash128<T>(T value, UInt128 seed = default) where T : unmanaged
}

public static class Hash128Extension
{
    extension(File)
    {
        public static UInt128 Hash128(string filePath, int bufferSize = 4096, UInt128 seed = default, FileShare share = FileShare.Read)
        public static async Task<UInt128> Hash128Async(string filePath, int bufferSize = 4096, UInt128 seed = default, FileShare share = FileShare.Read, CancellationToken cancellationToken = default)
    }
    
    extension(string? str)
    {
        public UInt128 Hash128(UInt128 seed = default)
    }
    
    extension<T>(ReadOnlySpan<T> buffer) where T : unmanaged
    {
        public UInt128 Hash128(UInt128 seed = default)
    }
    
    extension<T>(Span<T> buffer) where T : unmanaged
    {
        public UInt128 Hash128(UInt128 seed = default)
    }
    
    extension<T>(T[]? array) where T : unmanaged
    {
        public UInt128 Hash128(UInt128 seed = default)
    }
    
    extension<T>(List<T>? list) where T : unmanaged
    {
        public UInt128 Hash128(UInt128 seed = default)
    }
    
    extension(Stream stream)
    {
        public UInt128 Hash128(int bufferSize = 4096, UInt128 seed = default)
        
        public async Task<UInt128> Hash128Async(int bufferSize = 4096, UInt128 seed = default, CancellationToken cancellationToken = default)
    }
    
    extension<T>(T value) where T : unmanaged
    {
        public UInt128 Hash128(UInt128 seed = default)
    }
}

Memory Padding and Hash Consistency

Unmanaged structures often contain padding bytes inserted by the compiler for memory alignment. These padding bytes are uninitialized and can contain arbitrary values from previous memory operations, causing identical logical data to produce different hash values. To ensure consistent hashing across different data sources and environments, it's essential to zero out padding bytes before hashing. For a detailed explanation of this issue and an automated solution, see the StructPadding, which provides high-performance clearing of padding bytes in unmanaged structures.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.3.0 158 11/23/2025

1.3.0: Asynchronous overloads have been added. Fixed a bug with incorrect length calculation for Span(T).
           1.2.2: Added .NET 10, Extension methods.
           1.2.0: Added overloads for T.
           1.1.0: Added overloads for List.
           1.0.0: First version