From 7bbc69b9235e4cbe86505555acc4be9eca43d215 Mon Sep 17 00:00:00 2001 From: Hawkynt Date: Sat, 29 Aug 2026 21:31:24 +0200 Subject: [PATCH 1/6] # CI declared concurrency twice and stopped parsing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two concurrency blocks landed in the same mapping at the same time — one from me, one already there. A duplicate key makes the whole workflow unreadable, so every run since has been a parse failure: no jobs, no checks, and pull requests blocked with nothing to show why. The one that was there first is kept. It says the same thing. --- .github/workflows/ci.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c8fdb8d11..58c0af990 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,15 +15,6 @@ concurrency: group: ci-${{ github.event_name }}-${{ github.ref }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} -# One run per pull request at a time. Pushing again while checks are running -# supersedes them, and without this the old run keeps a runner busy: a handful -# of quick force-pushes left a dozen doomed runs queued ahead of the one that -# mattered, and everything behind them starved. Pushes to main are left alone — -# each commit there deserves its own verdict. -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: ${{ github.event_name == 'pull_request' }} - # Force JavaScript-based actions to run on Node 24 instead of the deprecated Node 20 ahead of # the 2026-06-16 hard cutover, until we bump each action to a Node-24-native major version. env: From a9393254fd797fa23272741acbf672aba5797311 Mon Sep 17 00:00:00 2001 From: Hawkynt Date: Sat, 29 Aug 2026 21:45:50 +0200 Subject: [PATCH 2/6] * regenerate the hashing and checksum API references --- Hawkynt.Algorithms.Checksums/README.md | 2 + Hawkynt.Algorithms.Checksums/REFERENCE.md | 663 ++++++++++ Hawkynt.Algorithms.Hashing/README.md | 2 + Hawkynt.Algorithms.Hashing/REFERENCE.md | 1361 +++++++++++++++++++++ 4 files changed, 2028 insertions(+) create mode 100644 Hawkynt.Algorithms.Checksums/REFERENCE.md create mode 100644 Hawkynt.Algorithms.Hashing/REFERENCE.md diff --git a/Hawkynt.Algorithms.Checksums/README.md b/Hawkynt.Algorithms.Checksums/README.md index f28b447d1..2b5036ad4 100644 --- a/Hawkynt.Algorithms.Checksums/README.md +++ b/Hawkynt.Algorithms.Checksums/README.md @@ -112,6 +112,8 @@ Legacy CompressionWorkbench call sites may continue to use the compatibility typ +Every public and protected member of all 69 types, generated from the built assembly and its XML documentation, is in [REFERENCE.md](https://github.com/Hawkynt/CompressionWorkbench/blob/main/Hawkynt.Algorithms.Checksums/REFERENCE.md). + ## 🏗 Architecture diff --git a/Hawkynt.Algorithms.Checksums/REFERENCE.md b/Hawkynt.Algorithms.Checksums/REFERENCE.md new file mode 100644 index 000000000..5c8fc0283 --- /dev/null +++ b/Hawkynt.Algorithms.Checksums/REFERENCE.md @@ -0,0 +1,663 @@ +# Hawkynt.Algorithms.Checksums — API reference + +[← Hawkynt.Algorithms.Checksums](https://github.com/Hawkynt/CompressionWorkbench/blob/main/Hawkynt.Algorithms.Checksums/README.md) + + + +> Every public and protected type and member, read from the built assembly and merged +> with its XML documentation. Generated — edit the XML docs in source, not this file. + +### Namespace `Compression.Core.Checksums` + +[`Adler32`](#adler32) · [`Adler32ChecksumSizeExtensions`](#adler32checksumsizeextensions) · [`Crc16`](#crc16) · [`Crc16Ccitt`](#crc16ccitt) · [`Crc16CcittChecksumSizeExtensions`](#crc16ccittchecksumsizeextensions) · [`Crc16ChecksumSizeExtensions`](#crc16checksumsizeextensions) · [`Crc32`](#crc32) · [`Crc32ChecksumSizeExtensions`](#crc32checksumsizeextensions) · [`Crc64`](#crc64) · [`Crc64ChecksumSizeExtensions`](#crc64checksumsizeextensions) · [`IChecksum`](#ichecksum) · [`ReedSolomon`](#reedsolomon) + +#### `Adler32` + +Adler-32 checksum as used by zlib, with Nmax optimization and SIMD vectorization. + +Implements `IChecksum`. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Adler32` | `Adler32()` | | +| `Value` | `uint Value { get; }` | | +| `Compute` | `static uint Compute(ReadOnlySpan data)` | Computes the Adler-32 of the given data in a single call. | +| `Reset` | `void Reset()` | | +| `Update` | `void Update(ReadOnlySpan data)` | | +| `Update` | `void Update(byte b)` | | + +#### `Adler32ChecksumSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedChecksumSizes` | `static IReadOnlyList get_SupportedChecksumSizes()` | | + +#### `Crc16` + +Table-driven CRC-16 implementation with configurable polynomial. + +Implements `IChecksum`. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Crc16` | `Crc16(ushort polynomial = 40961, ushort initialValue = 0)` | Initializes a new `Crc16` with the specified polynomial. | +| `Arc` | `const ushort Arc` | CRC-16/ARC polynomial (reflected form). | +| `Value` | `uint Value { get; }` | | +| `Compute` | `static ushort Compute(ReadOnlySpan data)` | Computes the CRC-16 of the given data using the ARC polynomial. | +| `Reset` | `void Reset()` | | +| `Update` | `void Update(ReadOnlySpan data)` | | +| `Update` | `void Update(byte b)` | | + +#### `Crc16Ccitt` + +Table-driven CRC-16/CCITT implementation (non-reflected form). Polynomial 0x1021, MSB-first. Used by ECMA-167 / UDF descriptor tags, XMODEM (init=0x0000) and CCITT-FALSE (init=0xFFFF) variants. + +Implements `IChecksum`. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Crc16Ccitt` | `Crc16Ccitt(ushort initialValue = 0)` | Initializes a new `Crc16Ccitt` with the specified initial value. | +| `Polynomial` | `const ushort Polynomial` | CRC-16/CCITT polynomial (non-reflected form). | +| `Value` | `uint Value { get; }` | | +| `Compute` | `static ushort Compute(ReadOnlySpan data, ushort initial = 0)` | Computes the CRC-16/CCITT of the given data. | +| `Reset` | `void Reset()` | | +| `Update` | `void Update(ReadOnlySpan data)` | | +| `Update` | `void Update(byte b)` | | + +#### `Crc16CcittChecksumSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedChecksumSizes` | `static IReadOnlyList get_SupportedChecksumSizes()` | | + +#### `Crc16ChecksumSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedChecksumSizes` | `static IReadOnlyList get_SupportedChecksumSizes()` | | + +#### `Crc32` + +Table-driven CRC-32 implementation with configurable polynomial, slicing-by-4 acceleration, and hardware intrinsics for SSE4.2 (CRC-32C), PCLMULQDQ (IEEE), and ARM CRC32 when available. + +Implements `IChecksum`. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Crc32` | `Crc32(uint polynomial = 3988292384)` | Initializes a new `Crc32` with the specified polynomial. | +| `Castagnoli` | `const uint Castagnoli` | Castagnoli (CRC-32C) polynomial. | +| `Ieee` | `const uint Ieee` | Standard IEEE 802.3 polynomial (used by ZIP, GZIP, PNG, etc.). | +| `Value` | `uint Value { get; }` | | +| `Compute` | `static uint Compute(ReadOnlySpan data)` | Computes the CRC-32 of the given data in a single call using the IEEE polynomial. | +| `Compute` | `static uint Compute(ReadOnlySpan data, uint polynomial)` | Computes the CRC-32 of the given data with the specified polynomial. | +| `Reset` | `void Reset()` | | +| `Update` | `void Update(ReadOnlySpan data)` | | +| `Update` | `void Update(byte b)` | | + +#### `Crc32ChecksumSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedChecksumSizes` | `static IReadOnlyList get_SupportedChecksumSizes()` | | + +#### `Crc64` + +Table-driven CRC-64 implementation with configurable polynomial and slicing-by-4 acceleration. + +Implements `IChecksum`. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Crc64` | `Crc64(ulong polynomial = 14514072000185962306)` | Initializes a new `Crc64` with the specified polynomial. | +| `Ecma182` | `const ulong Ecma182` | ECMA-182 polynomial used by the XZ format. | +| `Value64` | `ulong Value64 { get; }` | Gets the full 64-bit CRC value. | +| `Compute` | `static ulong Compute(ReadOnlySpan data)` | Computes the CRC-64 of the given data in a single call using the ECMA-182 polynomial. | +| `Reset` | `void Reset()` | | +| `Update` | `void Update(ReadOnlySpan data)` | | +| `Update` | `void Update(byte b)` | | + +#### `Crc64ChecksumSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedChecksumSizes` | `static IReadOnlyList get_SupportedChecksumSizes()` | | + +#### `IChecksum` + +Common interface for checksum algorithms. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Value` | `uint Value { get; }` | Gets the current checksum value. | +| `Reset` | `void Reset()` | Resets the checksum to its initial state. | +| `Update` | `void Update(ReadOnlySpan data)` | Updates the checksum with a span of bytes. | +| `Update` | `void Update(byte b)` | Updates the checksum with a single byte. | + +#### `ReedSolomon` + +Reed-Solomon encoder/decoder over GF(2^8) using primitive polynomial 0x11D (x^8 + x^4 + x^3 + x^2 + 1). Used for recovery records in archive formats. + +| Member | Signature | Summary | +| --- | --- | --- | +| `ReedSolomon` | `ReedSolomon(int dataShards, int parityShards)` | Creates a Reed-Solomon codec with the specified number of data and parity shards. | +| `Encode` | `byte[][] Encode(byte[][] data)` | Encodes data shards to produce parity shards. | +| `Reconstruct` | `bool Reconstruct(byte[][] shards)` | Reconstructs missing data shards using surviving data and parity shards. | + +### Namespace `Hawkynt.Algorithms.Checksums` + +[`AbaRouting`](#abarouting) · [`Adler`](#adler) · [`AdlerChecksumSizeExtensions`](#adlerchecksumsizeextensions) · [`AdlerGeneralizedChecksumExtensions`](#adlergeneralizedchecksumextensions) · [`BsdChecksum`](#bsdchecksum) · [`BsdChecksumSizeExtensions`](#bsdchecksumsizeextensions) · [`ChecksumSizeRange`](#checksumsizerange) · [`ChecksumSizeRange.Enumerator`](#checksumsizerangeenumerator) · [`ChecksumSizeRangeExtensions`](#checksumsizerangeextensions) · [`ComplementChecksum`](#complementchecksum) · [`ComplementChecksumSizeExtensions`](#complementchecksumsizeextensions) · [`ComplementGeneralizedChecksumExtensions`](#complementgeneralizedchecksumextensions) · [`ComplementKind`](#complementkind) · [`ConstantWeight`](#constantweight) · [`Crc`](#crc) · [`Crc128`](#crc128) · [`Crc128ChecksumSizeExtensions`](#crc128checksumsizeextensions) · [`Crc128Parameters`](#crc128parameters) · [`Crc128Presets`](#crc128presets) · [`CrcChecksumSizeExtensions`](#crcchecksumsizeextensions) · [`CrcParameters`](#crcparameters) · [`CrcPresets`](#crcpresets) · [`Cusip`](#cusip) · [`Damm`](#damm) · [`Fletcher`](#fletcher) · [`FletcherChecksumSizeExtensions`](#fletcherchecksumsizeextensions) · [`FletcherGeneralizedChecksumExtensions`](#fletchergeneralizedchecksumextensions) · [`Gtin`](#gtin) · [`Iban`](#iban) · [`Iccid`](#iccid) · [`Imei`](#imei) · [`InternetChecksum`](#internetchecksum) · [`InternetChecksumSizeExtensions`](#internetchecksumsizeextensions) · [`Isbn`](#isbn) · [`Isin`](#isin) · [`Issn`](#issn) · [`Lrc`](#lrc) · [`LrcChecksumSizeExtensions`](#lrcchecksumsizeextensions) · [`Luhn`](#luhn) · [`ModuloCheckDigit`](#modulocheckdigit) · [`Nmea0183`](#nmea0183) · [`Nmea0183ChecksumSizeExtensions`](#nmea0183checksumsizeextensions) · [`Npi`](#npi) · [`Parity`](#parity) · [`ParityChecksumSizeExtensions`](#paritychecksumsizeextensions) · [`ParityGeneralizedChecksumExtensions`](#paritygeneralizedchecksumextensions) · [`PostalBarcode`](#postalbarcode) · [`Sedol`](#sedol) · [`SumChecksum`](#sumchecksum) · [`SumChecksumSizeExtensions`](#sumchecksumsizeextensions) · [`SumGeneralizedChecksumExtensions`](#sumgeneralizedchecksumextensions) · [`SysVChecksum`](#sysvchecksum) · [`SysVChecksumSizeExtensions`](#sysvchecksumsizeextensions) · [`Verhoeff`](#verhoeff) · [`Vin`](#vin) · [`XorChecksum`](#xorchecksum) · [`XorChecksumSizeExtensions`](#xorchecksumsizeextensions) + +#### `AbaRouting` + +ABA routing transit number check digit. + +| Member | Signature | Summary | +| --- | --- | --- | +| `GenerateCheckDigit` | `static int GenerateCheckDigit(ReadOnlySpan firstEightDigits)` | | +| `Validate` | `static bool Validate(ReadOnlySpan routingNumber)` | | + +#### `Adler` + +Adler checksum family matching the variants in Hawkynt's algorithm registry. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute16` | `static ushort Compute16(ReadOnlySpan data)` | | +| `Compute32` | `static uint Compute32(ReadOnlySpan data)` | | +| `Compute64` | `static ulong Compute64(ReadOnlySpan data)` | | + +#### `AdlerChecksumSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedChecksumSizes` | `static IReadOnlyList get_SupportedChecksumSizes()` | | + +#### `AdlerGeneralizedChecksumExtensions` + +Arbitrary-width Adler checksum entry point. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, int checksumSizeBits)` | | + +#### `BsdChecksum` + +BSD rotating checksum used by historic `sum -r`. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static ushort Compute(ReadOnlySpan data)` | | + +#### `BsdChecksumSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedChecksumSizes` | `static IReadOnlyList get_SupportedChecksumSizes()` | | + +#### `ChecksumSizeRange` + +Describes a contiguous arithmetic range of supported checksum-output sizes, in bits. + +Implements `IEnumerable`, `IEnumerable`, `IEquatable`. + +| Member | Signature | Summary | +| --- | --- | --- | +| `ChecksumSizeRange` | `ChecksumSizeRange(int MinimumBits, int MaximumBits, int StepBits = 1)` | Describes a contiguous arithmetic range of supported checksum-output sizes, in bits. | +| `MaximumBits` | `int MaximumBits { get; init; }` | | +| `MinimumBits` | `int MinimumBits { get; init; }` | | +| `StepBits` | `int StepBits { get; init; }` | | +| `Contains` | `bool Contains(int bits)` | | +| `Exact` | `static ChecksumSizeRange Exact(int bits)` | | +| `GetEnumerator` | `Enumerator GetEnumerator()` | | + +#### `ChecksumSizeRange.Enumerator` + +Implements `IDisposable`, `IEnumerator`, `IEnumerator`. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Enumerator` | `Enumerator(ChecksumSizeRange range)` | | +| `Current` | `int Current { get; }` | | +| `Dispose` | `void Dispose()` | | +| `MoveNext` | `bool MoveNext()` | | +| `Reset` | `void Reset()` | | + +#### `ChecksumSizeRangeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `EnumerateSizes` | `static IEnumerable EnumerateSizes(this IReadOnlyList ranges)` | | +| `Supports` | `static bool Supports(this IReadOnlyList ranges, int bits)` | | + +#### `ComplementChecksum` + +One's and two's complement checksum helpers. + +| Member | Signature | Summary | +| --- | --- | --- | +| `OnesComplement16` | `static ushort OnesComplement16(ReadOnlySpan data)` | | +| `TwosComplement16` | `static ushort TwosComplement16(ReadOnlySpan data)` | | +| `TwosComplement8` | `static byte TwosComplement8(ReadOnlySpan data)` | | + +#### `ComplementChecksumSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedChecksumSizes` | `static IReadOnlyList get_SupportedChecksumSizes()` | | + +#### `ComplementGeneralizedChecksumExtensions` + +Arbitrary-width complement checksum entry point. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, int checksumSizeBits, ComplementKind kind = 1)` | | + +#### `ComplementKind` + +Selects the complement arithmetic used by `ComplementChecksum`. + +| Value | Numeric | Summary | +| --- | --- | --- | +| `OnesComplement` | `0` | | +| `TwosComplement` | `1` | | + +#### `ConstantWeight` + +Constant-weight validation helper. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Validate` | `static bool Validate(ReadOnlySpan data, int expectedOneBits)` | | + +#### `Crc` + +Bit-accurate generic CRC implementation using normal-form polynomials. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute16` | `static ushort Compute16(ReadOnlySpan data, CrcParameters parameters)` | | +| `Compute24` | `static uint Compute24(ReadOnlySpan data, CrcParameters parameters)` | | +| `Compute32` | `static uint Compute32(ReadOnlySpan data, CrcParameters parameters)` | | +| `Compute64` | `static ulong Compute64(ReadOnlySpan data, CrcParameters parameters)` | | +| `Compute8` | `static byte Compute8(ReadOnlySpan data, CrcParameters parameters)` | | +| `Compute` | `static ulong Compute(ReadOnlySpan data, CrcParameters parameters)` | | + +#### `Crc128` + +Generic 128-bit CRC using normal-form polynomials. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static UInt128 Compute(ReadOnlySpan data, Crc128Parameters parameters)` | | + +#### `Crc128ChecksumSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedChecksumSizes` | `static IReadOnlyList get_SupportedChecksumSizes()` | | + +#### `Crc128Parameters` + +Parameters for the educational 128-bit CRC variants in the source registry. + +Implements `IEquatable`. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Crc128Parameters` | `Crc128Parameters(UInt128 Polynomial, UInt128 InitialValue, bool ReflectInput, bool ReflectOutput, UInt128 FinalXor)` | Parameters for the educational 128-bit CRC variants in the source registry. | +| `FinalXor` | `UInt128 FinalXor { get; init; }` | | +| `InitialValue` | `UInt128 InitialValue { get; init; }` | | +| `Polynomial` | `UInt128 Polynomial { get; init; }` | | +| `ReflectInput` | `bool ReflectInput { get; init; }` | | +| `ReflectOutput` | `bool ReflectOutput { get; init; }` | | + +#### `Crc128Presets` + +128-bit CRC presets carried by the educational source registry. + +| Member | Signature | Summary | +| --- | --- | --- | +| `BigData` | `static readonly Crc128Parameters BigData` | | +| `Hpc` | `static readonly Crc128Parameters Hpc` | | +| `Standard` | `static readonly Crc128Parameters Standard` | | + +#### `CrcChecksumSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedChecksumSizes` | `static IReadOnlyList get_SupportedChecksumSizes()` | | + +#### `CrcParameters` + +Parameters for CRC widths from 8 through 64 bits. + +Implements `IEquatable`. + +| Member | Signature | Summary | +| --- | --- | --- | +| `CrcParameters` | `CrcParameters(int Width, ulong Polynomial, ulong InitialValue, bool ReflectInput, bool ReflectOutput, ulong FinalXor)` | Parameters for CRC widths from 8 through 64 bits. | +| `FinalXor` | `ulong FinalXor { get; init; }` | | +| `InitialValue` | `ulong InitialValue { get; init; }` | | +| `Polynomial` | `ulong Polynomial { get; init; }` | | +| `ReflectInput` | `bool ReflectInput { get; init; }` | | +| `ReflectOutput` | `bool ReflectOutput { get; init; }` | | +| `Width` | `int Width { get; init; }` | | + +#### `CrcPresets` + +CRC parameter presets represented by the JavaScript source registry plus common interoperable aliases. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Crc16Ansi` | `static readonly CrcParameters Crc16Ansi` | | +| `Crc16Arc` | `static readonly CrcParameters Crc16Arc` | | +| `Crc16Ccitt` | `static readonly CrcParameters Crc16Ccitt` | | +| `Crc16Ibm` | `static readonly CrcParameters Crc16Ibm` | | +| `Crc16Xmodem` | `static readonly CrcParameters Crc16Xmodem` | | +| `Crc24FlexRay` | `static readonly CrcParameters Crc24FlexRay` | | +| `Crc24Interlaken` | `static readonly CrcParameters Crc24Interlaken` | | +| `Crc24OpenPgp` | `static readonly CrcParameters Crc24OpenPgp` | | +| `Crc32Bzip2` | `static readonly CrcParameters Crc32Bzip2` | | +| `Crc32Castagnoli` | `static readonly CrcParameters Crc32Castagnoli` | | +| `Crc32Ieee` | `static readonly CrcParameters Crc32Ieee` | | +| `Crc32Posix` | `static readonly CrcParameters Crc32Posix` | | +| `Crc64Ecma182` | `static readonly CrcParameters Crc64Ecma182` | | +| `Crc64We` | `static readonly CrcParameters Crc64We` | | +| `Crc64Xz` | `static readonly CrcParameters Crc64Xz` | | +| `Crc8Autosar` | `static readonly CrcParameters Crc8Autosar` | | +| `Crc8Cdma2000` | `static readonly CrcParameters Crc8Cdma2000` | | +| `Crc8Maxim` | `static readonly CrcParameters Crc8Maxim` | | +| `Crc8Smbus` | `static readonly CrcParameters Crc8Smbus` | | + +#### `Cusip` + +CUSIP check digit. + +| Member | Signature | Summary | +| --- | --- | --- | +| `GenerateCheckDigit` | `static int GenerateCheckDigit(ReadOnlySpan firstEightCharacters)` | | +| `Validate` | `static bool Validate(ReadOnlySpan cusip)` | | + +#### `Damm` + +Damm check digit using the standard anti-symmetric quasigroup. + +| Member | Signature | Summary | +| --- | --- | --- | +| `GenerateCheckDigit` | `static int GenerateCheckDigit(ReadOnlySpan payload)` | | +| `Validate` | `static bool Validate(ReadOnlySpan digits)` | | + +#### `Fletcher` + +Fletcher checksum family. The 32/64-bit variants deliberately consume bytes, matching the source registry. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute16` | `static ushort Compute16(ReadOnlySpan data)` | | +| `Compute32` | `static uint Compute32(ReadOnlySpan data)` | | +| `Compute64` | `static ulong Compute64(ReadOnlySpan data)` | | +| `Compute8` | `static byte Compute8(ReadOnlySpan data)` | | + +#### `FletcherChecksumSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedChecksumSizes` | `static IReadOnlyList get_SupportedChecksumSizes()` | | + +#### `FletcherGeneralizedChecksumExtensions` + +Arbitrary-width Fletcher checksum entry point. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, int checksumSizeBits)` | | + +#### `Gtin` + +EAN/UPC/GTIN modulo-10 check digits. + +| Member | Signature | Summary | +| --- | --- | --- | +| `GenerateCheckDigit` | `static int GenerateCheckDigit(ReadOnlySpan payload)` | | +| `GenerateEan13` | `static int GenerateEan13(ReadOnlySpan twelveDigits)` | | +| `GenerateEan8` | `static int GenerateEan8(ReadOnlySpan sevenDigits)` | | +| `GenerateUpcA` | `static int GenerateUpcA(ReadOnlySpan elevenDigits)` | | +| `Validate` | `static bool Validate(ReadOnlySpan value)` | | + +#### `Iban` + +International Bank Account Number MOD-97 validation. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Validate` | `static bool Validate(ReadOnlySpan iban)` | | + +#### `Iccid` + +ICCID check digit (Luhn). + +| Member | Signature | Summary | +| --- | --- | --- | +| `GenerateCheckDigit` | `static int GenerateCheckDigit(ReadOnlySpan payload)` | | +| `Validate` | `static bool Validate(ReadOnlySpan iccid)` | | + +#### `Imei` + +IMEI check digit (Luhn). + +| Member | Signature | Summary | +| --- | --- | --- | +| `GenerateCheckDigit` | `static int GenerateCheckDigit(ReadOnlySpan fourteenDigits)` | | +| `Validate` | `static bool Validate(ReadOnlySpan imei)` | | + +#### `InternetChecksum` + +Internet checksum from RFC 1071 (one's-complement sum of big-endian 16-bit words). + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static ushort Compute(ReadOnlySpan data)` | | +| `Verify` | `static bool Verify(ReadOnlySpan dataIncludingChecksum)` | | + +#### `InternetChecksumSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedChecksumSizes` | `static IReadOnlyList get_SupportedChecksumSizes()` | | + +#### `Isbn` + +ISBN-10 and ISBN-13 check digits. + +| Member | Signature | Summary | +| --- | --- | --- | +| `GenerateIsbn10CheckDigit` | `static char GenerateIsbn10CheckDigit(ReadOnlySpan firstNineDigits)` | | +| `GenerateIsbn13CheckDigit` | `static int GenerateIsbn13CheckDigit(ReadOnlySpan firstTwelveDigits)` | | +| `ValidateIsbn10` | `static bool ValidateIsbn10(ReadOnlySpan isbn)` | | +| `ValidateIsbn13` | `static bool ValidateIsbn13(ReadOnlySpan isbn)` | | + +#### `Isin` + +ISIN check digit (ISO 6166 letter expansion followed by Luhn). + +| Member | Signature | Summary | +| --- | --- | --- | +| `GenerateCheckDigit` | `static int GenerateCheckDigit(ReadOnlySpan elevenCharacters)` | | +| `Validate` | `static bool Validate(ReadOnlySpan isin)` | | + +#### `Issn` + +ISSN modulo-11 check digit. + +| Member | Signature | Summary | +| --- | --- | --- | +| `GenerateCheckDigit` | `static char GenerateCheckDigit(ReadOnlySpan firstSevenDigits)` | | +| `Validate` | `static bool Validate(ReadOnlySpan issn)` | | + +#### `Lrc` + +Longitudinal redundancy check (two's complement of the 8-bit byte sum). + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte Compute(ReadOnlySpan data)` | | + +#### `LrcChecksumSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedChecksumSizes` | `static IReadOnlyList get_SupportedChecksumSizes()` | | + +#### `Luhn` + +Luhn modulo-10 check digit. + +| Member | Signature | Summary | +| --- | --- | --- | +| `GenerateCheckDigit` | `static int GenerateCheckDigit(ReadOnlySpan payload)` | | +| `Validate` | `static bool Validate(ReadOnlySpan digits)` | | + +#### `ModuloCheckDigit` + +Generic weighted modulo check-digit helper. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Generate` | `static int Generate(ReadOnlySpan payload, ReadOnlySpan weights, int modulus, bool complement = true)` | | + +#### `Nmea0183` + +NMEA-0183 XOR checksum. Delimiters '$'/'!' and '*' plus suffix are ignored when present. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte Compute(ReadOnlySpan sentence)` | | + +#### `Nmea0183ChecksumSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedChecksumSizes` | `static IReadOnlyList get_SupportedChecksumSizes()` | | + +#### `Npi` + +US National Provider Identifier check digit. + +| Member | Signature | Summary | +| --- | --- | --- | +| `GenerateCheckDigit` | `static int GenerateCheckDigit(ReadOnlySpan firstNineDigits)` | | +| `Validate` | `static bool Validate(ReadOnlySpan npi)` | | + +#### `Parity` + +Parity helpers. + +| Member | Signature | Summary | +| --- | --- | --- | +| `BitParity` | `static int BitParity(byte value)` | | +| `BlockParity` | `static byte BlockParity(ReadOnlySpan data)` | | +| `EvenParityBit` | `static byte EvenParityBit(byte value)` | | +| `OddParityBit` | `static byte OddParityBit(byte value)` | | + +#### `ParityChecksumSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedChecksumSizes` | `static IReadOnlyList get_SupportedChecksumSizes()` | | + +#### `ParityGeneralizedChecksumExtensions` + +Arbitrary-width longitudinal parity entry point. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, int checksumSizeBits)` | | + +#### `PostalBarcode` + +POSTNET and PLANET barcode check digit (sum of digits completed to a multiple of 10). + +| Member | Signature | Summary | +| --- | --- | --- | +| `GenerateCheckDigit` | `static int GenerateCheckDigit(ReadOnlySpan payload)` | | +| `Validate` | `static bool Validate(ReadOnlySpan value)` | | + +#### `Sedol` + +SEDOL check digit. + +| Member | Signature | Summary | +| --- | --- | --- | +| `GenerateCheckDigit` | `static int GenerateCheckDigit(ReadOnlySpan firstSixCharacters)` | | +| `Validate` | `static bool Validate(ReadOnlySpan sedol)` | | + +#### `SumChecksum` + +Simple additive checksum variants. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute16` | `static ushort Compute16(ReadOnlySpan data)` | | +| `Compute32` | `static uint Compute32(ReadOnlySpan data)` | | +| `Compute8` | `static byte Compute8(ReadOnlySpan data)` | | + +#### `SumChecksumSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedChecksumSizes` | `static IReadOnlyList get_SupportedChecksumSizes()` | | + +#### `SumGeneralizedChecksumExtensions` + +Arbitrary-width additive checksum entry point. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, int checksumSizeBits)` | | + +#### `SysVChecksum` + +System V checksum used by historic `sum -s`. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static ushort Compute(ReadOnlySpan data)` | | + +#### `SysVChecksumSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedChecksumSizes` | `static IReadOnlyList get_SupportedChecksumSizes()` | | + +#### `Verhoeff` + +Verhoeff check digit using the dihedral group D5 tables. + +| Member | Signature | Summary | +| --- | --- | --- | +| `GenerateCheckDigit` | `static int GenerateCheckDigit(ReadOnlySpan payload)` | | +| `Validate` | `static bool Validate(ReadOnlySpan digits)` | | + +#### `Vin` + +Vehicle Identification Number check digit. + +| Member | Signature | Summary | +| --- | --- | --- | +| `GenerateCheckDigit` | `static char GenerateCheckDigit(ReadOnlySpan vinWithoutReliableCheckDigit)` | | +| `Validate` | `static bool Validate(ReadOnlySpan vin)` | | + +#### `XorChecksum` + +XOR checksum, also used by NMEA-0183 sentence checksums. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte Compute(ReadOnlySpan data)` | | + +#### `XorChecksumSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedChecksumSizes` | `static IReadOnlyList get_SupportedChecksumSizes()` | | diff --git a/Hawkynt.Algorithms.Hashing/README.md b/Hawkynt.Algorithms.Hashing/README.md index 00532f31a..3a0e1c606 100644 --- a/Hawkynt.Algorithms.Hashing/README.md +++ b/Hawkynt.Algorithms.Hashing/README.md @@ -136,6 +136,8 @@ Standard algorithms may share a parameterized managed implementation. Source-spe +Every public and protected member of all 180 types, generated from the built assembly and its XML documentation, is in [REFERENCE.md](https://github.com/Hawkynt/CompressionWorkbench/blob/main/Hawkynt.Algorithms.Hashing/REFERENCE.md). + ## 🏗 Architecture diff --git a/Hawkynt.Algorithms.Hashing/REFERENCE.md b/Hawkynt.Algorithms.Hashing/REFERENCE.md new file mode 100644 index 000000000..0a128e057 --- /dev/null +++ b/Hawkynt.Algorithms.Hashing/REFERENCE.md @@ -0,0 +1,1361 @@ +# Hawkynt.Algorithms.Hashing — API reference + +[← Hawkynt.Algorithms.Hashing](https://github.com/Hawkynt/CompressionWorkbench/blob/main/Hawkynt.Algorithms.Hashing/README.md) + + + +> Every public and protected type and member, read from the built assembly and merged +> with its XML documentation. Generated — edit the XML docs in source, not this file. + +### Namespace `Compression.Core.Checksums` + +[`Blake2b`](#blake2b) · [`Blake2bHashSizeExtensions`](#blake2bhashsizeextensions) · [`Md5`](#md5) · [`Md5HashSizeExtensions`](#md5hashsizeextensions) · [`Sha1`](#sha1) · [`Sha1HashSizeExtensions`](#sha1hashsizeextensions) · [`Sha256`](#sha256) · [`Sha256HashSizeExtensions`](#sha256hashsizeextensions) · [`XxHash32`](#xxhash32) · [`XxHash32HashSizeExtensions`](#xxhash32hashsizeextensions) · [`XxHash64`](#xxhash64) · [`XxHash64HashSizeExtensions`](#xxhash64hashsizeextensions) + +#### `Blake2b` + +BLAKE2b cryptographic hash function (RFC 7693). Produces digests of 1–64 bytes (default 32). Operates on 64-bit words and is optimised for 64-bit platforms. Provides both batch (`Compute`) and incremental (`Update`/`Finish`) modes. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Blake2b` | `Blake2b(int hashSize = 32)` | Initializes a new `Blake2b` instance. | +| `DefaultHashSize` | `const int DefaultHashSize` | Default hash size in bytes (256 bits). | +| `MaxHashSize` | `const int MaxHashSize` | Maximum hash size in bytes (512 bits). | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, int hashSize = 32)` | Computes a BLAKE2b hash over the given data in one shot. | +| `Finish` | `byte[] Finish()` | Finalises the hash and returns the digest. | +| `Reset` | `void Reset()` | Resets the hash state for reuse. | +| `Update` | `void Update(ReadOnlySpan data)` | Feeds data into the hash. | + +#### `Blake2bHashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Md5` + +MD5 hash function (RFC 1321). Produces 16-byte (128-bit) message digests. Used for legacy key derivation in formats like SQX. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | Computes the MD5 hash of the given data. | + +#### `Md5HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Sha1` + +FIPS 180-4 SHA-1 cryptographic hash function. Provides both batch (`Compute`) and incremental (`Update`/`Finish`) modes. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Sha1` | `Sha1()` | Initializes a new `Sha1` instance. | +| `HashSize` | `const int HashSize` | The size of the SHA-1 hash output in bytes (20 bytes / 160 bits). | +| `Hash` | `byte[] Hash { get; }` | Gets the computed hash. Available after `Finish` has been called. | +| `Clone` | `Sha1 Clone()` | Creates a copy of the current hasher state, allowing independent continuation. | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | Computes the SHA-1 hash of the given data in a single call. | +| `Finish` | `void Finish()` | Finalizes the hash computation. | +| `Reset` | `void Reset()` | Resets the hasher to its initial state. | +| `Update` | `void Update(ReadOnlySpan data)` | Updates the hash with additional data. | + +#### `Sha1HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Sha256` + +FIPS 180-4 SHA-256 cryptographic hash function. Provides both batch (`Compute`) and incremental (`Update`/`Finish`) modes. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Sha256` | `Sha256()` | Initializes a new `Sha256` instance. | +| `HashSize` | `const int HashSize` | The size of the SHA-256 hash output in bytes (32 bytes / 256 bits). | +| `Hash` | `byte[] Hash { get; }` | Gets the computed hash. Available after `Finish` has been called. Returns an empty array before finalization. | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | Computes the SHA-256 hash of the given data in a single call. | +| `Finish` | `void Finish()` | Finalizes the hash computation. After calling this method, the `Hash` property contains the 32-byte SHA-256 digest. | +| `Reset` | `void Reset()` | Resets the hasher to its initial state. | +| `Update` | `void Update(ReadOnlySpan data)` | Updates the hash with additional data. | + +#### `Sha256HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `XxHash32` + +xxHash 32-bit non-cryptographic hash function. Provides both batch (`Compute`) and incremental (`Update`/`Value`) modes. + +| Member | Signature | Summary | +| --- | --- | --- | +| `XxHash32` | `XxHash32(uint seed = 0)` | Initializes a new `XxHash32` with the specified seed. | +| `Value` | `uint Value { get; }` | Gets the current hash value. This finalizes the accumulated state without modifying it. | +| `Compute` | `static uint Compute(ReadOnlySpan data, uint seed = 0)` | Computes the xxHash32 of the given data in a single call. | +| `Reset` | `void Reset()` | Resets the hasher to its initial state. | +| `Update` | `void Update(ReadOnlySpan data)` | Updates the hash with additional data. | + +#### `XxHash32HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `XxHash64` + +xxHash 64-bit non-cryptographic hash function. Provides both batch (`Compute`) and incremental (`Update`/`Value`) modes. + +| Member | Signature | Summary | +| --- | --- | --- | +| `XxHash64` | `XxHash64(ulong seed = 0)` | Initializes a new `XxHash64` with the specified seed. | +| `Value` | `ulong Value { get; }` | Gets the current hash value. This finalizes the accumulated state without modifying it. | +| `Compute` | `static ulong Compute(ReadOnlySpan data, ulong seed = 0)` | Computes the xxHash64 of the given data in a single call. | +| `Reset` | `void Reset()` | Resets the hasher to its initial state. | +| `Update` | `void Update(ReadOnlySpan data)` | Updates the hash with additional data. | + +#### `XxHash64HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +### Namespace `Hawkynt.Algorithms.Hashing` + +[`AsconHash`](#asconhash) · [`AsconHashSizeExtensions`](#asconhashsizeextensions) · [`AsconXof`](#asconxof) · [`Blake`](#blake) · [`Blake2s`](#blake2s) · [`Blake2sHashSizeExtensions`](#blake2shashsizeextensions) · [`Blake2xs`](#blake2xs) · [`Blake3`](#blake3) · [`Blake3Enhanced`](#blake3enhanced) · [`BlakeHashSizeExtensions`](#blakehashsizeextensions) · [`CShake`](#cshake) · [`ChcHash`](#chchash) · [`ChcHashSizeExtensions`](#chchashsizeextensions) · [`CityHash`](#cityhash) · [`CityHashSizeExtensions`](#cityhashsizeextensions) · [`Comb4PMd4Md5`](#comb4pmd4md5) · [`Comb4PMd4Md5HashSizeExtensions`](#comb4pmd4md5hashsizeextensions) · [`Comb4PSha1Ripemd160`](#comb4psha1ripemd160) · [`Comb4PSha1Ripemd160HashSizeExtensions`](#comb4psha1ripemd160hashsizeextensions) · [`CubeHash256`](#cubehash256) · [`CubeHash256HashSizeExtensions`](#cubehash256hashsizeextensions) · [`CubeHash512`](#cubehash512) · [`CubeHash512HashSizeExtensions`](#cubehash512hashsizeextensions) · [`DarkCryptKeccak`](#darkcryptkeccak) · [`DarkCryptKeccakHashSizeExtensions`](#darkcryptkeccakhashsizeextensions) · [`DarkCryptMd6`](#darkcryptmd6) · [`DarkCryptMd6HashSizeExtensions`](#darkcryptmd6hashsizeextensions) · [`DarkCryptSkein`](#darkcryptskein) · [`DarkCryptSkeinHashSizeExtensions`](#darkcryptskeinhashsizeextensions) · [`DryGasconHash`](#drygasconhash) · [`Echo`](#echo) · [`Echo224`](#echo224) · [`Echo224HashSizeExtensions`](#echo224hashsizeextensions) · [`Echo256`](#echo256) · [`Echo256HashSizeExtensions`](#echo256hashsizeextensions) · [`Echo384`](#echo384) · [`Echo384HashSizeExtensions`](#echo384hashsizeextensions) · [`Echo512`](#echo512) · [`Echo512HashSizeExtensions`](#echo512hashsizeextensions) · [`Esch256`](#esch256) · [`Esch256HashSizeExtensions`](#esch256hashsizeextensions) · [`Esch384`](#esch384) · [`Esch384HashSizeExtensions`](#esch384hashsizeextensions) · [`Fnv`](#fnv) · [`FnvHashSizeExtensions`](#fnvhashsizeextensions) · [`Fugue`](#fugue) · [`Gimli24Hash`](#gimli24hash) · [`Gimli24HashSizeExtensions`](#gimli24hashsizeextensions) · [`Gost3411HashSizeExtensions`](#gost3411hashsizeextensions) · [`Gost3411_94`](#gost3411_94) · [`Groestl`](#groestl) · [`Groestl224`](#groestl224) · [`Groestl224HashSizeExtensions`](#groestl224hashsizeextensions) · [`Groestl256`](#groestl256) · [`Groestl256HashSizeExtensions`](#groestl256hashsizeextensions) · [`Groestl384`](#groestl384) · [`Groestl384HashSizeExtensions`](#groestl384hashsizeextensions) · [`Groestl512`](#groestl512) · [`Groestl512HashSizeExtensions`](#groestl512hashsizeextensions) · [`Hamsi`](#hamsi) · [`HamsiFamily`](#hamsifamily) · [`Haraka256`](#haraka256) · [`Haraka256HashSizeExtensions`](#haraka256hashsizeextensions) · [`Haraka512`](#haraka512) · [`Haraka512HashSizeExtensions`](#haraka512hashsizeextensions) · [`HashSizeRange`](#hashsizerange) · [`HashSizeRange.Enumerator`](#hashsizerangeenumerator) · [`HashSizeRangeExtensions`](#hashsizerangeextensions) · [`Haval`](#haval) · [`HavalHashSizeExtensions`](#havalhashsizeextensions) · [`HighwayHash`](#highwayhash) · [`IsapHash`](#isaphash) · [`IsapHashSizeExtensions`](#isaphashsizeextensions) · [`Jh`](#jh) · [`KangarooTwelve`](#kangarootwelve) · [`Keccak`](#keccak) · [`KnotHash`](#knothash) · [`KnotHashVariant`](#knothashvariant) · [`Kupyna`](#kupyna) · [`Lsh224`](#lsh224) · [`Lsh224HashSizeExtensions`](#lsh224hashsizeextensions) · [`Lsh256`](#lsh256) · [`Lsh256Family`](#lsh256family) · [`Lsh256HashSizeExtensions`](#lsh256hashsizeextensions) · [`Lsh384`](#lsh384) · [`Lsh384HashSizeExtensions`](#lsh384hashsizeextensions) · [`Lsh512`](#lsh512) · [`Lsh512Family`](#lsh512family) · [`Lsh512HashSizeExtensions`](#lsh512hashsizeextensions) · [`Lsh512_256`](#lsh512_256) · [`Lsh512_256HashSizeExtensions`](#lsh512_256hashsizeextensions) · [`Luffa`](#luffa) · [`Luffa224`](#luffa224) · [`Luffa224HashSizeExtensions`](#luffa224hashsizeextensions) · [`Luffa256`](#luffa256) · [`Luffa256HashSizeExtensions`](#luffa256hashsizeextensions) · [`Luffa384`](#luffa384) · [`Luffa384HashSizeExtensions`](#luffa384hashsizeextensions) · [`Luffa512`](#luffa512) · [`Luffa512HashSizeExtensions`](#luffa512hashsizeextensions) · [`Md2`](#md2) · [`Md2HashSizeExtensions`](#md2hashsizeextensions) · [`Md4`](#md4) · [`Md4HashSizeExtensions`](#md4hashsizeextensions) · [`Mdc2`](#mdc2) · [`Mdc2HashSizeExtensions`](#mdc2hashsizeextensions) · [`MurmurHash3`](#murmurhash3) · [`MurmurHash3HashSizeExtensions`](#murmurhash3hashsizeextensions) · [`PanamaBE`](#panamabe) · [`PanamaBEHashSizeExtensions`](#panamabehashsizeextensions) · [`PanamaBEMac`](#panamabemac) · [`PanamaLE`](#panamale) · [`PanamaLEHashSizeExtensions`](#panamalehashsizeextensions) · [`PanamaLEMac`](#panamalemac) · [`ParallelHash`](#parallelhash) · [`PhotonBeetleHash`](#photonbeetlehash) · [`PhotonBeetleHashSizeExtensions`](#photonbeetlehashsizeextensions) · [`RadioGatun32`](#radiogatun32) · [`Ripemd`](#ripemd) · [`Ripemd128`](#ripemd128) · [`Ripemd128HashSizeExtensions`](#ripemd128hashsizeextensions) · [`Ripemd160`](#ripemd160) · [`Ripemd160HashSizeExtensions`](#ripemd160hashsizeextensions) · [`Ripemd256`](#ripemd256) · [`Ripemd256HashSizeExtensions`](#ripemd256hashsizeextensions) · [`Ripemd320`](#ripemd320) · [`Ripemd320HashSizeExtensions`](#ripemd320hashsizeextensions) · [`Sha3`](#sha3) · [`Sha3HashSizeExtensions`](#sha3hashsizeextensions) · [`Sha512Family`](#sha512family) · [`Shabal192`](#shabal192) · [`Shabal192HashSizeExtensions`](#shabal192hashsizeextensions) · [`Shabal224`](#shabal224) · [`Shabal224HashSizeExtensions`](#shabal224hashsizeextensions) · [`Shabal256`](#shabal256) · [`Shabal256HashSizeExtensions`](#shabal256hashsizeextensions) · [`Shabal384`](#shabal384) · [`Shabal384HashSizeExtensions`](#shabal384hashsizeextensions) · [`Shabal512`](#shabal512) · [`Shabal512HashSizeExtensions`](#shabal512hashsizeextensions) · [`Shake`](#shake) · [`SipHash24`](#siphash24) · [`SipHash24HashSizeExtensions`](#siphash24hashsizeextensions) · [`Skein512`](#skein512) · [`Skein512HashSizeExtensions`](#skein512hashsizeextensions) · [`SkinnyHash`](#skinnyhash) · [`SkinnyHashVariant`](#skinnyhashvariant) · [`Sm3`](#sm3) · [`Sm3HashSizeExtensions`](#sm3hashsizeextensions) · [`SparkleHash`](#sparklehash) · [`SparkleHashSizeExtensions`](#sparklehashsizeextensions) · [`Streebog`](#streebog) · [`Streebog256`](#streebog256) · [`Streebog256HashSizeExtensions`](#streebog256hashsizeextensions) · [`Streebog512`](#streebog512) · [`Streebog512HashSizeExtensions`](#streebog512hashsizeextensions) · [`SubterraneanHash`](#subterraneanhash) · [`SubterraneanHashSizeExtensions`](#subterraneanhashsizeextensions) · [`Tiger`](#tiger) · [`TupleHash`](#tuplehash) · [`Whirlpool`](#whirlpool) · [`WhirlpoolHashSizeExtensions`](#whirlpoolhashsizeextensions) · [`XoodyakHash`](#xoodyakhash) · [`XoodyakHashSizeExtensions`](#xoodyakhashsizeextensions) · [`XxHash`](#xxhash) · [`XxHash3`](#xxhash3) · [`XxHash3HashSizeExtensions`](#xxhash3hashsizeextensions) · [`XxHashHashSizeExtensions`](#xxhashhashsizeextensions) + +#### `AsconHash` + +ASCON-HASH / Ascon-Hash256 variant carried by the JavaScript registry. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `AsconHashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `AsconXof` + +ASCON-XOF variant carried by the JavaScript registry. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, int outputBytes)` | | + +#### `Blake` + +Original BLAKE SHA-3 finalist family. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute224` | `static byte[] Compute224(ReadOnlySpan data)` | | +| `Compute256` | `static byte[] Compute256(ReadOnlySpan data)` | | +| `Compute384` | `static byte[] Compute384(ReadOnlySpan data)` | | +| `Compute512` | `static byte[] Compute512(ReadOnlySpan data)` | | + +#### `Blake2s` + +BLAKE2s-256. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Blake2sHashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Blake2xs` + +BLAKE2xs extendable-output function. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, int outputBytes)` | | + +#### `Blake3` + +BLAKE3 hash and XOF. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, int outputBytes = 32)` | | + +#### `Blake3Enhanced` + +Registry-compatible BLAKE3-Enhanced surface, backed by the same complete BLAKE3 core. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, int outputBytes = 32)` | | + +#### `BlakeHashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `CShake` + +cSHAKE customizable XOF functions from NIST SP 800-185. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute128` | `static byte[] Compute128(ReadOnlySpan data, int outputBytes, ReadOnlySpan functionName = null, ReadOnlySpan customization = null)` | | +| `Compute256` | `static byte[] Compute256(ReadOnlySpan data, int outputBytes, ReadOnlySpan functionName = null, ReadOnlySpan customization = null)` | | + +#### `ChcHash` + +Cipher Hash Construction using the source registry's default AES-128 Matyas-Meyer-Oseas construction. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `ChcHashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `CityHash` + +Google's CityHash64. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute64` | `static ulong Compute64(ReadOnlySpan data)` | The 64-bit hash of `data`. | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | The 64-bit hash of `data`, most significant byte first. | + +#### `CityHashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Comb4PMd4Md5` + +COMB4P(MD4, MD5) hash combiner. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Comb4PMd4Md5HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Comb4PSha1Ripemd160` + +COMB4P(SHA-1, RIPEMD-160) hash combiner. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Comb4PSha1Ripemd160HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `CubeHash256` + +CubeHash16+16/32+16-256. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `CubeHash256HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `CubeHash512` + +CubeHash16+16/32+16-512. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `CubeHash512HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `DarkCryptKeccak` + +Keccak variant used by the DarkCrypt Total Commander plugin. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `DarkCryptKeccakHashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `DarkCryptMd6` + +MD6-512 variant emitted by the DarkCrypt Total Commander plugin. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `DarkCryptMd6HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `DarkCryptSkein` + +Skein-512-512 variant used by the DarkCrypt Total Commander plugin. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `DarkCryptSkeinHashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `DryGasconHash` + +DryGASCON hash family from the NIST lightweight-cryptography finalist. + +| Member | Signature | Summary | +| --- | --- | --- | +| `SupportedHashSizes` | `static IReadOnlyList SupportedHashSizes { get; }` | | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, int hashSizeBits = 256)` | | + +#### `Echo` + +ECHO SHA-3 candidate family facade over the shared ECHO core. + +| Member | Signature | Summary | +| --- | --- | --- | +| `SupportedHashSizes` | `static IReadOnlyList SupportedHashSizes { get; }` | | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, int hashSizeBits = 256)` | | + +#### `Echo224` + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Echo224HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Echo256` + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Echo256HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Echo384` + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Echo384HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Echo512` + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Echo512HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Esch256` + +Esch256 based on SPARKLE-384. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Esch256HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Esch384` + +Esch384 based on SPARKLE-512. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Esch384HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Fnv` + +Fowler-Noll-Vo hash family. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute1A_32` | `static uint Compute1A_32(ReadOnlySpan data, uint offsetBasis = 2166136261)` | | +| `Compute1A_64` | `static ulong Compute1A_64(ReadOnlySpan data, ulong offsetBasis = 14695981039346656037)` | | +| `Compute1_32` | `static uint Compute1_32(ReadOnlySpan data, uint offsetBasis = 2166136261)` | | +| `Compute1_64` | `static ulong Compute1_64(ReadOnlySpan data, ulong offsetBasis = 14695981039346656037)` | | + +#### `FnvHashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Fugue` + +Fugue SHA-3 candidate family. All digest sizes share the same state-machine implementation; the selected digest size chooses the Fugue-2, Fugue-3 or Fugue-4 round schedule. + +| Member | Signature | Summary | +| --- | --- | --- | +| `SupportedHashSizes` | `static IReadOnlyList SupportedHashSizes { get; }` | | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, int hashSizeBits = 256)` | | + +#### `Gimli24Hash` + +GIMLI-24-HASH lightweight 256-bit hash. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Gimli24HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Gost3411HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Gost3411_94` + +GOST R 34.11-94 using the D-A GOST 28147-89 S-box. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Groestl` + +Grøstl hash family with a single implementation selected by output size. + +| Member | Signature | Summary | +| --- | --- | --- | +| `SupportedHashSizes` | `static IReadOnlyList SupportedHashSizes { get; }` | | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, int hashSizeBits = 256)` | | + +#### `Groestl224` + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Groestl224HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Groestl256` + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Groestl256HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Groestl384` + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Groestl384HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Groestl512` + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Groestl512HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Hamsi` + +Hamsi big-state family. Hamsi-384 and Hamsi-512 share the same 512-bit-state compression implementation; digest selection changes only the IV and the standardized output truncation. + +| Member | Signature | Summary | +| --- | --- | --- | +| `SupportedHashSizes` | `static IReadOnlyList SupportedHashSizes { get; }` | | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, int hashSizeBits = 512)` | | + +#### `HamsiFamily` + +Hamsi SHA-3 candidate family. The standardized output sizes are exposed as two enumerable ranges, matching the JavaScript registry model. Output size selects one of Hamsi's two standardized state widths; each state width has one shared compression implementation. + +| Member | Signature | Summary | +| --- | --- | --- | +| `SupportedHashSizes` | `static IReadOnlyList SupportedHashSizes { get; }` | | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, int hashSizeBits = 256)` | | + +#### `Haraka256` + +Haraka v2 256-bit fixed-input hash. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Haraka256HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Haraka512` + +Haraka v2 512-to-256 fixed-input hash. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Haraka512HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `HashSizeRange` + +Describes a contiguous arithmetic range of supported hash-output sizes, in bits. + +Implements `IEnumerable`, `IEnumerable`, `IEquatable`. + +| Member | Signature | Summary | +| --- | --- | --- | +| `HashSizeRange` | `HashSizeRange(int MinimumBits, int MaximumBits, int StepBits = 1)` | Describes a contiguous arithmetic range of supported hash-output sizes, in bits. | +| `MaximumBits` | `int MaximumBits { get; init; }` | | +| `MinimumBits` | `int MinimumBits { get; init; }` | | +| `StepBits` | `int StepBits { get; init; }` | | +| `Contains` | `bool Contains(int bits)` | | +| `Exact` | `static HashSizeRange Exact(int bits)` | | +| `GetEnumerator` | `Enumerator GetEnumerator()` | | + +#### `HashSizeRange.Enumerator` + +Implements `IDisposable`, `IEnumerator`, `IEnumerator`. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Enumerator` | `Enumerator(HashSizeRange range)` | | +| `Current` | `int Current { get; }` | | +| `Dispose` | `void Dispose()` | | +| `MoveNext` | `bool MoveNext()` | | +| `Reset` | `void Reset()` | | + +#### `HashSizeRangeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `EnumerateSizes` | `static IEnumerable EnumerateSizes(this IReadOnlyList ranges)` | | +| `Supports` | `static bool Supports(this IReadOnlyList ranges, int bits)` | | + +#### `Haval` + +HAVAL variable-pass, variable-output cryptographic hash. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute128` | `static byte[] Compute128(ReadOnlySpan data, int passes = 3)` | | +| `Compute160` | `static byte[] Compute160(ReadOnlySpan data, int passes = 4)` | | +| `Compute192` | `static byte[] Compute192(ReadOnlySpan data, int passes = 4)` | | +| `Compute224` | `static byte[] Compute224(ReadOnlySpan data, int passes = 4)` | | +| `Compute256` | `static byte[] Compute256(ReadOnlySpan data, int passes = 5)` | | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, int passes = 5, int outputBits = 256)` | | + +#### `HavalHashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `HighwayHash` + +Google HighwayHash portable 64-, 128-, and 256-bit keyed hash. + +| Member | Signature | Summary | +| --- | --- | --- | +| `SupportedHashSizes` | `static IReadOnlyList SupportedHashSizes { get; }` | | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, ReadOnlySpan key, int hashSizeBits = 64)` | | + +#### `IsapHash` + +ISAP Hash. The registry's ISAP digest uses the same precomputed Ascon-Hash state, 64-bit rate, P12 absorption, padding, and squeezing as ASCON-HASH. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `IsapHashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Jh` + +JH variant carried by the JavaScript algorithm registry. + +| Member | Signature | Summary | +| --- | --- | --- | +| `SupportedHashSizes` | `static IReadOnlyList SupportedHashSizes { get; }` | | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, int hashSizeBits = 512)` | | + +#### `KangarooTwelve` + +KangarooTwelve extendable-output function using Keccak-p[1600,12]. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, int outputBytes = 32, ReadOnlySpan personalization = null)` | | + +#### `Keccak` + +Keccak-f[1600] sponge primitives and standard Keccak/SHA-3/SHAKE variants. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute224` | `static byte[] Compute224(ReadOnlySpan data)` | | +| `Compute256` | `static byte[] Compute256(ReadOnlySpan data)` | | +| `Compute384` | `static byte[] Compute384(ReadOnlySpan data)` | | +| `Compute512` | `static byte[] Compute512(ReadOnlySpan data)` | | + +#### `KnotHash` + +KNOT-HASH family with explicit parameter-set selection. + +| Member | Signature | Summary | +| --- | --- | --- | +| `SupportedHashSizes` | `static IReadOnlyList SupportedHashSizes { get; }` | | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, KnotHashVariant variant = 0)` | | + +#### `KnotHashVariant` + +The four standardized KNOT-HASH parameter sets. + +| Value | Numeric | Summary | +| --- | --- | --- | +| `KnotHash256_256` | `0` | KNOT-HASH-256-256: 256-bit digest over the 256-bit permutation. | +| `KnotHash256_384` | `1` | KNOT-HASH-256-384: 256-bit digest over the 384-bit permutation. | +| `KnotHash384_384` | `2` | KNOT-HASH-384-384: 384-bit digest over the 384-bit permutation. | +| `KnotHash512_512` | `3` | KNOT-HASH-512-512: 512-bit digest over the 512-bit permutation. | + +#### `Kupyna` + +DSTU 7564:2014 (Kupyna) hash family. The 256-, 384- and 512-bit digests share one permutation/compression implementation; the digest size selects the state width and truncation. + +| Member | Signature | Summary | +| --- | --- | --- | +| `SupportedHashSizes` | `static IReadOnlyList SupportedHashSizes { get; }` | | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, int hashSizeBits = 256)` | | + +#### `Lsh224` + +Korean LSH-224 hash function. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Lsh224HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Lsh256` + +Korean LSH-256 hash function. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Lsh256Family` + +LSH-256 word-size family; output size selects the standard IV/truncation. + +| Member | Signature | Summary | +| --- | --- | --- | +| `SupportedHashSizes` | `static IReadOnlyList SupportedHashSizes { get; }` | | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, int hashSizeBits = 256)` | | + +#### `Lsh256HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Lsh384` + +Korean LSH-384 hash function. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Lsh384HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Lsh512` + +Korean LSH-512 hash function. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Lsh512Family` + +LSH-512 word-size family; output size selects the standard IV/truncation. + +| Member | Signature | Summary | +| --- | --- | --- | +| `SupportedHashSizes` | `static IReadOnlyList SupportedHashSizes { get; }` | | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, int hashSizeBits = 512)` | | + +#### `Lsh512HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Lsh512_256` + +Korean LSH-512/256 hash function. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Lsh512_256HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Luffa` + +Luffa SHA-3 candidate family facade over the shared Luffa core. + +| Member | Signature | Summary | +| --- | --- | --- | +| `SupportedHashSizes` | `static IReadOnlyList SupportedHashSizes { get; }` | | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, int hashSizeBits = 256)` | | + +#### `Luffa224` + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Luffa224HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Luffa256` + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Luffa256HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Luffa384` + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Luffa384HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Luffa512` + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Luffa512HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Md2` + +MD2 from RFC 1319. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Md2HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Md4` + +MD4 from RFC 1320. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Md4HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Mdc2` + +Modification Detection Code 2 (MDC-2), including both OpenSSL padding modes carried by the JavaScript source. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, int paddingType = 1)` | | + +#### `Mdc2HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `MurmurHash3` + +MurmurHash3 x86-32 and x64-128 variants. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute128Bytes` | `static byte[] Compute128Bytes(ReadOnlySpan data, ulong seed = 0)` | | +| `Compute128` | `static ValueTuple Compute128(ReadOnlySpan data, ulong seed = 0)` | | +| `Compute32` | `static uint Compute32(ReadOnlySpan data, uint seed = 0)` | | + +#### `MurmurHash3HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `PanamaBE` + +Big-endian Panama hash. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `PanamaBEHashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `PanamaBEMac` + +Panama-BE hermetic MAC used by the registry implementation. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, ReadOnlySpan key)` | | + +#### `PanamaLE` + +Little-endian Panama hash. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `PanamaLEHashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `PanamaLEMac` + +Panama-LE hermetic MAC used by the registry implementation. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, ReadOnlySpan key)` | | + +#### `ParallelHash` + +ParallelHash from NIST SP 800-185. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute128` | `static byte[] Compute128(ReadOnlySpan data, int blockBytes, int outputBytes, ReadOnlySpan customization = null)` | | +| `Compute256` | `static byte[] Compute256(ReadOnlySpan data, int blockBytes, int outputBytes, ReadOnlySpan customization = null)` | | + +#### `PhotonBeetleHash` + +PhotonBeetle 256-bit hash from the NIST lightweight-cryptography finalist. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `PhotonBeetleHashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `RadioGatun32` + +RadioGatún[32] belt-and-mill hash function. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, int outputBytes = 32)` | | + +#### `Ripemd` + +RIPEMD family facade over the shared RIPEMD core. + +| Member | Signature | Summary | +| --- | --- | --- | +| `SupportedHashSizes` | `static IReadOnlyList SupportedHashSizes { get; }` | | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, int hashSizeBits = 160)` | | + +#### `Ripemd128` + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Ripemd128HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Ripemd160` + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Ripemd160HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Ripemd256` + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Ripemd256HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Ripemd320` + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Ripemd320HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Sha3` + +SHA-3 family from FIPS 202. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute224` | `static byte[] Compute224(ReadOnlySpan data)` | | +| `Compute256` | `static byte[] Compute256(ReadOnlySpan data)` | | +| `Compute384` | `static byte[] Compute384(ReadOnlySpan data)` | | +| `Compute512` | `static byte[] Compute512(ReadOnlySpan data)` | | + +#### `Sha3HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Sha512Family` + +SHA-384, SHA-512, SHA-512/224 and SHA-512/256 from FIPS 180-4. + +| Member | Signature | Summary | +| --- | --- | --- | +| `SupportedHashSizes` | `static IReadOnlyList SupportedHashSizes { get; }` | | +| `Compute384` | `static byte[] Compute384(ReadOnlySpan data)` | | +| `Compute512_224` | `static byte[] Compute512_224(ReadOnlySpan data)` | | +| `Compute512_256` | `static byte[] Compute512_256(ReadOnlySpan data)` | | +| `Compute512` | `static byte[] Compute512(ReadOnlySpan data)` | | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, int hashSizeBits = 512)` | | + +#### `Shabal192` + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Shabal192HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Shabal224` + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Shabal224HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Shabal256` + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Shabal256HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Shabal384` + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Shabal384HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Shabal512` + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Shabal512HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Shake` + +SHAKE extendable-output functions from FIPS 202. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute128` | `static byte[] Compute128(ReadOnlySpan data, int outputBytes)` | | +| `Compute256` | `static byte[] Compute256(ReadOnlySpan data, int outputBytes)` | | + +#### `SipHash24` + +SipHash-2-4 keyed 64-bit hash. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static ulong Compute(ReadOnlySpan data, ReadOnlySpan key)` | | + +#### `SipHash24HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Skein512` + +Skein-512-512 from the Skein 1.3 specification. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Skein512HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `SkinnyHash` + +SKINNY-HASH lightweight hash family based on SKINNY-128. + +| Member | Signature | Summary | +| --- | --- | --- | +| `SupportedHashSizes` | `static IReadOnlyList SupportedHashSizes { get; }` | | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, SkinnyHashVariant variant = 0)` | | + +#### `SkinnyHashVariant` + +The two SKINNY-HASH tweakey-state variants. + +| Value | Numeric | Summary | +| --- | --- | --- | +| `Tk2` | `0` | SKINNY-tk2-HASH: 32-byte state and 4-byte absorption rate. | +| `Tk3` | `1` | SKINNY-tk3-HASH: 48-byte state and 16-byte absorption rate. | + +#### `Sm3` + +SM3 Chinese national cryptographic hash standard (GB/T 32905). + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Sm3HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `SparkleHash` + +Registry name for the Esch256/SPARKLE-384 construction. The JavaScript registry implementation is byte-for-byte the Esch256 algorithm. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `SparkleHashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Streebog` + +Streebog (GOST R 34.11-2012) hash family with one implementation for both standard sizes. + +| Member | Signature | Summary | +| --- | --- | --- | +| `SupportedHashSizes` | `static IReadOnlyList SupportedHashSizes { get; }` | | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, int hashSizeBits = 512)` | | + +#### `Streebog256` + +Streebog-256 (GOST R 34.11-2012) hash function. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Streebog256HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Streebog512` + +Streebog-512 (GOST R 34.11-2012) hash function. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `Streebog512HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `SubterraneanHash` + +Subterranean-Hash, a 256-bit lightweight hash based on the 257-bit Subterranean permutation. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `SubterraneanHashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `Tiger` + +Tiger, the 192-bit hash by Ross Anderson and Eli Biham. + +| Member | Signature | Summary | +| --- | --- | --- | +| `SupportedHashSizes` | `static IReadOnlyList SupportedHashSizes { get; }` | | +| `Compute` | `static byte[] Compute(ReadOnlySpan data, int hashSizeBits = 192)` | | + +#### `TupleHash` + +TupleHash from NIST SP 800-185. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute128` | `static byte[] Compute128(IEnumerable> tuple, int outputBytes, ReadOnlySpan customization = null)` | | +| `Compute256` | `static byte[] Compute256(IEnumerable> tuple, int outputBytes, ReadOnlySpan customization = null)` | | + +#### `Whirlpool` + +Whirlpool as standardized in ISO/IEC 10118-3. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `WhirlpoolHashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `XoodyakHash` + +Xoodyak hash mode from the JavaScript registry. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute` | `static byte[] Compute(ReadOnlySpan data)` | | + +#### `XoodyakHashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `XxHash` + +Generic xxHash registry facade. The registry defaults to xxHash32 and optionally exposes xxHash64. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute32` | `static uint Compute32(ReadOnlySpan data, uint seed = 0)` | | +| `Compute64` | `static ulong Compute64(ReadOnlySpan data, ulong seed = 0)` | | + +#### `XxHash3` + +xxHash3 registry implementation, including its 64- and 128-bit output modes. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Compute128` | `static byte[] Compute128(ReadOnlySpan data, ulong seed = 0)` | | +| `Compute64Bytes` | `static byte[] Compute64Bytes(ReadOnlySpan data, ulong seed = 0)` | | +| `Compute64` | `static ulong Compute64(ReadOnlySpan data, ulong seed = 0)` | | + +#### `XxHash3HashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | + +#### `XxHashHashSizeExtensions` + +| Member | Signature | Summary | +| --- | --- | --- | +| `get_SupportedHashSizes` | `static IReadOnlyList get_SupportedHashSizes()` | | From 2306f0dbe609fba45c74ea74a1c37e2a01f55e80 Mon Sep 17 00:00:00 2001 From: Hawkynt Date: Sat, 29 Aug 2026 22:27:12 +0200 Subject: [PATCH 3/6] # three faults that landed while CI could not run With the workflow unparseable nothing was verified, so these went in unchecked. A written Unreal package was read back as a Quake one: both claim ".pak", and Quake announces itself in the first four bytes while Unreal keeps its magic in the footer, where a leading-bytes check never looks. A written VMware bundle was read back as a Veeam backup, which claims ".vib" as well; the bundle is an AR archive and says so in its first eight bytes. Both are settled by content now, the way ".arc", ".dsk" and ".wad" already are. Keccak advertised no digest sizes and was not in the contract test's registry. --- Compression.Lib/FormatDetector.cs | 68 +++++++++++++++++++ .../SupportedHashSizesContractTests.cs | 1 + .../Algorithms/Keccak.cs | 6 ++ 3 files changed, 75 insertions(+) diff --git a/Compression.Lib/FormatDetector.cs b/Compression.Lib/FormatDetector.cs index 645ff3b95..90fe809d9 100644 --- a/Compression.Lib/FormatDetector.cs +++ b/Compression.Lib/FormatDetector.cs @@ -247,6 +247,23 @@ public static Format DetectByExtension(string path) { return cpc; } + // ".pak" is Quake's PACK archive and Unreal's package. Quake's magic is the + // leading "PACK"; Unreal's sits in the footer, so a leading-bytes check can + // never see it and every Unreal pak was routed to the Quake reader. + if (singleExt == ".pak") { + var pak = DetectPakByMagic(path); + if (pak != Format.Unknown) + return pak; + } + + // ".vib" is both a VMware installation bundle (an AR archive) and a Veeam + // incremental backup. Only one of the two says what it is up front. + if (singleExt == ".vib") { + var vib = DetectVibByMagic(path); + if (vib != Format.Unknown) + return vib; + } + // The ".arc" extension is shared by the legacy SEA ARC format (every entry // header starts with the 0x1A magic byte, the "Arc" descriptor) and FreeArc // (magic "ArC\x01", the "FreeArc" descriptor). The first-claim-wins map routes @@ -305,6 +322,57 @@ private static Format DetectCpcDskByMagic(string path) { /// format by reading the leading bytes. Returns /// when unreadable so the caller falls back to the registry extension map. /// + /// + /// Tells Quake's PACK archive from an Unreal package. Quake announces itself in + /// the first four bytes; Unreal keeps its magic in the footer, ahead of the + /// trailing index offset and length, so the tail is where it has to be read. + /// + private static Format DetectPakByMagic(string path) { + try { + if (!File.Exists(path)) return Format.Unknown; + using var fs = File.OpenRead(path); + Span magic = stackalloc byte[4]; + if (fs.Length >= 4) { + fs.ReadExactly(magic); + if (magic[0] == 'P' && magic[1] == 'A' && magic[2] == 'C' && magic[3] == 'K') + return Format.Pak; + } + + // The footer is 44 bytes for the versions that keep the magic at its front; + // later revisions prepend fields, so scan the tail rather than fix an offset. + var tail = (int)Math.Min(fs.Length, 256); + if (tail < 4) return Format.Unknown; + var buffer = new byte[tail]; + fs.Position = fs.Length - tail; + fs.ReadExactly(buffer); + for (var i = 0; i + 4 <= tail; ++i) + if (BinaryPrimitives.ReadUInt32LittleEndian(buffer.AsSpan(i, 4)) == 0x5A6F12E1) + return Format.UnrealPak; + } catch { + /* ignore detection failure */ + } + return Format.Unknown; + } + + /// + /// Tells a VMware installation bundle from a Veeam incremental backup. The + /// bundle is an AR archive and says so in its first eight bytes. + /// + private static Format DetectVibByMagic(string path) { + try { + if (!File.Exists(path)) return Format.Unknown; + using var fs = File.OpenRead(path); + if (fs.Length < 8) return Format.Unknown; + Span magic = stackalloc byte[8]; + fs.ReadExactly(magic); + if (magic.SequenceEqual("!\n"u8)) + return Format.Vib; + } catch { + /* ignore detection failure */ + } + return Format.Unknown; + } + private static Format DetectArcByMagic(string path) { try { if (!File.Exists(path)) return Format.Unknown; diff --git a/Compression.Tests/Hashing/SupportedHashSizesContractTests.cs b/Compression.Tests/Hashing/SupportedHashSizesContractTests.cs index 3c251a192..9a91a8681 100644 --- a/Compression.Tests/Hashing/SupportedHashSizesContractTests.cs +++ b/Compression.Tests/Hashing/SupportedHashSizesContractTests.cs @@ -69,6 +69,7 @@ public sealed class SupportedHashSizesContractTests { [typeof(Jh)] = static () => Jh.SupportedHashSizes, [typeof(Sha3)] = static () => Sha3.SupportedHashSizes, [typeof(KnotHash)] = static () => KnotHash.SupportedHashSizes, + [typeof(Keccak)] = static () => Keccak.SupportedHashSizes, [typeof(Kupyna)] = static () => Kupyna.SupportedHashSizes, [typeof(Md2)] = static () => Md2.SupportedHashSizes, [typeof(Md4)] = static () => Md4.SupportedHashSizes, diff --git a/Hawkynt.Algorithms.Hashing/Algorithms/Keccak.cs b/Hawkynt.Algorithms.Hashing/Algorithms/Keccak.cs index 61aaeb98b..89571af0b 100644 --- a/Hawkynt.Algorithms.Hashing/Algorithms/Keccak.cs +++ b/Hawkynt.Algorithms.Hashing/Algorithms/Keccak.cs @@ -6,6 +6,12 @@ namespace Hawkynt.Algorithms.Hashing; /// Keccak-f[1600] sponge primitives and standard Keccak/SHA-3/SHAKE variants. public static class Keccak { + /// The four standard Keccak digest sizes. + public static IReadOnlyList SupportedHashSizes { get; } = [ + new(224, 256, 32), + new(384, 512, 128) + ]; + private static readonly ulong[] RoundConstants = [ 0x0000000000000001UL, 0x0000000000008082UL, 0x800000000000808AUL, 0x8000000080008000UL, 0x000000000000808BUL, 0x0000000080000001UL, 0x8000000080008081UL, 0x8000000000008009UL, From 15131dfec9dabd128afc25ff50c9d337d1ba1260 Mon Sep 17 00:00:00 2001 From: Hawkynt Date: Sat, 29 Aug 2026 22:37:39 +0200 Subject: [PATCH 4/6] * regenerate the hashing API reference for Keccak's declared sizes --- Hawkynt.Algorithms.Hashing/REFERENCE.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Hawkynt.Algorithms.Hashing/REFERENCE.md b/Hawkynt.Algorithms.Hashing/REFERENCE.md index 0a128e057..c6136cc29 100644 --- a/Hawkynt.Algorithms.Hashing/REFERENCE.md +++ b/Hawkynt.Algorithms.Hashing/REFERENCE.md @@ -690,6 +690,7 @@ Keccak-f[1600] sponge primitives and standard Keccak/SHA-3/SHAKE variants. | Member | Signature | Summary | | --- | --- | --- | +| `SupportedHashSizes` | `static IReadOnlyList SupportedHashSizes { get; }` | The four standard Keccak digest sizes. | | `Compute224` | `static byte[] Compute224(ReadOnlySpan data)` | | | `Compute256` | `static byte[] Compute256(ReadOnlySpan data)` | | | `Compute384` | `static byte[] Compute384(ReadOnlySpan data)` | | From d029737c7902edb54d69636d0921c09162246e48 Mon Sep 17 00:00:00 2001 From: Hawkynt Date: Sat, 29 Aug 2026 23:04:07 +0200 Subject: [PATCH 5/6] + the two algorithm packages in the solution MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both are reached only as transitive project references, so nothing guarantees they are built before the Windows single-file bundle asks for their assemblies — and it failed there, unable to find Hawkynt.Algorithms.Checksums.dll. --- CompressionWorkbench.slnx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CompressionWorkbench.slnx b/CompressionWorkbench.slnx index c5756a0cc..6f558c5d6 100644 --- a/CompressionWorkbench.slnx +++ b/CompressionWorkbench.slnx @@ -1,5 +1,7 @@ + + From 08cdc4ca243171683b4c6460aa8fb70fc4ef010f Mon Sep 17 00:00:00 2001 From: Hawkynt Date: Sun, 30 Aug 2026 00:04:17 +0200 Subject: [PATCH 6/6] # BALZ could split its range below the interval it was splitting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The coder puts the split one below the scaled probability. Normalization only guarantees the top bytes of low and high differ, so the range can be small enough that the scaled probability truncates to zero — and the split then lands one below low. Encoding a zero bit set high under low, and everything after it was read from an inverted interval. The high side was already clamped; the low side was not. One random payload in a few thousand hit it, which is how it survived: the round-trip test draws its own bytes from Random.Shared, so the failure moved around. Seed 3138 at 64 KiB reproduces it — the literal 43020 symbols in came back one less than it went in, and the match after that pointed at a slot nothing had filled. 12000 round-trips over 6000 seeds and two sizes are clean. --- Compression.Tests/Balz/BalzTests.cs | 19 +++++++++++++++++++ FileFormats/FileFormat.Balz/BalzStream.cs | 10 ++++++++++ 2 files changed, 29 insertions(+) diff --git a/Compression.Tests/Balz/BalzTests.cs b/Compression.Tests/Balz/BalzTests.cs index 3aa567cc8..ee2920097 100644 --- a/Compression.Tests/Balz/BalzTests.cs +++ b/Compression.Tests/Balz/BalzTests.cs @@ -21,6 +21,25 @@ public void RoundTrip(int size) { Assert.That(decompressed.ToArray(), Is.EqualTo(data)); } + /// + /// This payload used to desynchronize the coder: on a small enough range the + /// scaled probability truncates to zero and the split point landed one below + /// low, so a zero bit set high under low. One literal came back wrong 43020 + /// symbols in, and the next match pointed at an empty slot. + /// + [Test] + public void RoundTrip_PayloadThatCollapsedTheRange() { + var data = new byte[65536]; + new Random(3138).NextBytes(data); + using var input = new MemoryStream(data); + using var compressed = new MemoryStream(); + BalzStream.Compress(input, compressed); + compressed.Position = 0; + using var decompressed = new MemoryStream(); + BalzStream.Decompress(compressed, decompressed); + Assert.That(decompressed.ToArray(), Is.EqualTo(data)); + } + [Test, Category("EdgeCase")] public void RoundTrip_Empty() { var data = Array.Empty(); diff --git a/FileFormats/FileFormat.Balz/BalzStream.cs b/FileFormats/FileFormat.Balz/BalzStream.cs index 446828382..04e31c594 100644 --- a/FileFormats/FileFormat.Balz/BalzStream.cs +++ b/FileFormats/FileFormat.Balz/BalzStream.cs @@ -189,6 +189,11 @@ private sealed class ArithEncoder { public void EncodeBit(int bit, ref int prob) { var range = _high - _low + 1; var mid = _low + (ulong)range * (uint)prob / (uint)ProbMax - 1; + // The split has to stay inside [low, high). Normalization only guarantees + // the top bytes differ, so the range can be small enough that the scaled + // probability truncates to zero — and then the "- 1" puts mid below low, + // where encoding a zero bit sets high under low and inverts the interval. + if (mid < _low) mid = _low; if (mid >= _high) mid = _high - 1; var umid = (uint)mid; @@ -235,6 +240,11 @@ public ArithDecoder(Stream input) { public int DecodeBit(ref int prob) { var range = _high - _low + 1; var mid = _low + (ulong)range * (uint)prob / (uint)ProbMax - 1; + // The split has to stay inside [low, high). Normalization only guarantees + // the top bytes differ, so the range can be small enough that the scaled + // probability truncates to zero — and then the "- 1" puts mid below low, + // where encoding a zero bit sets high under low and inverts the interval. + if (mid < _low) mid = _low; if (mid >= _high) mid = _high - 1; var umid = (uint)mid;