package core:hash/xxhash

⌘K
Ctrl+K
or
/

    Overview

    An implementation of Yann Collet's xxhash Fast Hash Algorithm.

    An implementation of Yann Collet's [xxhash Fast Hash Algorithm](https://cyan4973.github.io/xxHash/).
    Copyright 2021 Jeroen van Rijn <nom@duclavier.com>.
    
    Made available under Odin's BSD-3 license, based on the original C code.
    
    List of contributors:
    	Jeroen van Rijn: Initial implementation.
    
    An implementation of Yann Collet's [xxhash Fast Hash Algorithm](https://cyan4973.github.io/xxHash/).
    Copyright 2021 Jeroen van Rijn <nom@duclavier.com>.
    
    Made available under Odin's BSD-3 license, based on the original C code.
    
    List of contributors:
    	Jeroen van Rijn: Initial implementation.
    
    An implementation of Yann Collet's [xxhash Fast Hash Algorithm](https://cyan4973.github.io/xxHash/).
    Copyright 2021 Jeroen van Rijn <nom@duclavier.com>.
    
    Made available under Odin's BSD-3 license, based on the original C code.
    
    List of contributors:
    	Jeroen van Rijn: Initial implementation.
    
    An implementation of Yann Collet's [xxhash Fast Hash Algorithm](https://cyan4973.github.io/xxHash/).
    Copyright 2021 Jeroen van Rijn <nom@duclavier.com>.
    
    Made available under Odin's BSD-3 license, based on the original C code.
    
    List of contributors:
    	Jeroen van Rijn: Initial implementation.
    

    Index

    Procedures (99)
    Procedure Groups (2)

    Types

    Alignment ¶

    Alignment :: enum int {
    	Aligned, 
    	Unaligned, 
    }
    Related Procedures With Parameters

    XXH128_canonical ¶

    XXH128_canonical :: struct {
    	digest: [16]u8,
    }
    Related Procedures With Parameters
    Related Procedures With Returns

    XXH128_hash_t ¶

    XXH128_hash_t :: struct #raw_union {
    	using raw: struct {
    		low:  u64,
    		// !< `value & 0xFFFFFFFFFFFFFFFF` 
    		high: u64,
    	},
    	h:   u128,
    }
    Related Procedures With Parameters

    XXH32_canonical ¶

    XXH32_canonical :: struct {
    	digest: [4]u8,
    }
    Related Procedures With Parameters
    Related Procedures With Returns

    XXH32_hash ¶

    XXH32_hash :: u32
     

    32-bit hash functions

    XXH32_state ¶

    XXH32_state :: struct {
    	total_len_32: u32,
    	// !< Total length hashed, modulo 2^32 
    	large_len:    u32,
    	// !< Whether the hash is >= 16 (handles @ref total_len_32 overflow) 
    	v1:           u32,
    	// !< First accumulator lane 
    	v2:           u32,
    	// !< Second accumulator lane 
    	v3:           u32,
    	// !< Third accumulator lane 
    	v4:           u32,
    	// !< Fourth accumulator lane 
    	mem32:        [4]u32,
    	// !< Internal buffer for partial reads. Treated as unsigned char[16]. 
    	memsize:      u32,
    	// !< Amount of data in @ref mem32 
    	reserved:     u32,
    }
    Related Procedures With Parameters
    Related Procedures With Returns

    XXH3_128_hash ¶

    XXH3_128_hash :: u128

    XXH3_hashLong128_f ¶

    XXH3_hashLong128_f :: proc(input: []u8, seed: u64, secret: []u8) -> (res: u128)
    Related Procedures With Parameters

    XXH3_hashLong64_f ¶

    XXH3_hashLong64_f :: proc(input: []u8, seed: u64, secret: []u8) -> (res: u64)
    Related Procedures With Parameters

    XXH3_init_custom_secret_f ¶

    XXH3_init_custom_secret_f :: proc(custom_secret: []u8, seed64: u64)
    Related Procedures With Parameters

    XXH3_state ¶

    XXH3_state :: struct {
    	acc:               [8]u64,
    	custom_secret:     [192]u8,
    	buffer:            [256]u8,
    	buffered_size:     u32,
    	reserved32:        u32,
    	stripes_so_far:    uint,
    	total_length:      u64,
    	stripes_per_block: uint,
    	secret_limit:      uint,
    	seed:              u64,
    	reserved64:        u64,
    	external_secret:   []u8,
    }
     

    Streaming state.

    IMPORTANT: This structure has a strict alignment requirement of 64 bytes!! ** Do not allocate this with make() or new, it will not be sufficiently aligned. UseXXH3_create_state and `XXH3_destroy_state, or stack allocation.

    Related Procedures With Parameters
    Related Procedures With Returns

    XXH64_canonical ¶

    XXH64_canonical :: struct {
    	digest: [8]u8,
    }
    Related Procedures With Parameters
    Related Procedures With Returns

    XXH64_hash ¶

    XXH64_hash :: u64
     

    64-bit hash functions

    XXH64_state ¶

    XXH64_state :: struct {
    	total_len:  u64,
    	// !< Total length hashed. This is always 64-bit. 
    	v1:         u64,
    	// !< First accumulator lane 
    	v2:         u64,
    	// !< Second accumulator lane 
    	v3:         u64,
    	// !< Third accumulator lane 
    	v4:         u64,
    	// !< Fourth accumulator lane 
    	mem64:      [4]u64,
    	// !< Internal buffer for partial reads. Treated as unsigned char[32]. 
    	memsize:    u32,
    	// !< Amount of data in @ref mem64 
    	reserved32: u32,
    	// !< Reserved field, needed for padding anyways
    	reserved64: u64,
    }
    Related Procedures With Parameters
    Related Procedures With Returns

    xxh_u128 ¶

    xxh_u128 :: u128
     

    Stored in little endian order, although the fields themselves are in native endianness.

    xxh_u32 ¶

    xxh_u32 :: u32

    xxh_u64 ¶

    xxh_u64 :: u64

    Constants

    XXH32_DEFAULT_SEED ¶

    XXH32_DEFAULT_SEED: u32 : XXH32_hash(0)

    XXH3_INIT_ACC ¶

    XXH3_INIT_ACC: [8]u64 : [XXH_ACC_NB]xxh_u64{XXH_PRIME32_3, XXH_PRIME64_1, XXH_PRIME64_2, XXH_PRIME64_3, XXH_PRIME64_4, XXH_PRIME32_2, XXH_PRIME64_5, XXH_PRIME32_1}

    XXH3_INTERNAL_BUFFER_SIZE ¶

    XXH3_INTERNAL_BUFFER_SIZE :: 256
     

    This is the optimal update size for incremental hashing.

    XXH3_MIDSIZE_LASTOFFSET ¶

    XXH3_MIDSIZE_LASTOFFSET :: 17

    XXH3_MIDSIZE_MAX ¶

    XXH3_MIDSIZE_MAX :: 240

    XXH3_MIDSIZE_STARTOFFSET ¶

    XXH3_MIDSIZE_STARTOFFSET :: 3

    XXH3_SECRET_SIZE_MIN ¶

    XXH3_SECRET_SIZE_MIN :: 136
     

    Do not change this constant.

    XXH64_DEFAULT_SEED ¶

    XXH64_DEFAULT_SEED: u64 : XXH64_hash(0)

    XXH_ACC_ALIGN ¶

    XXH_ACC_ALIGN :: 8
     

    scalar

    XXH_ACC_NB ¶

    XXH_ACC_NB :: XXH_STRIPE_LEN / size_of(xxh_u64)

    XXH_DISABLE_PREFETCH ¶

    XXH_DISABLE_PREFETCH :: #config(XXH_DISABLE_PREFETCH, true)

    XXH_FORCE_ALIGN_CHECK ¶

    XXH_FORCE_ALIGN_CHECK :: #config(XXH_FORCE_ALIGN_CHECK, false)
     

    false - Use this on platforms where unaligned reads are fast true - Use this on platforms where unaligned reads are slow

    XXH_FORCE_MEMORY_ACCESS ¶

    XXH_FORCE_MEMORY_ACCESS :: #config(XXH_FORCE_MEMORY_ACCESS, 2)
     

    0 - Use memcopy, for platforms where unaligned reads are a problem 2 - Direct cast, for platforms where unaligned are allowed (default)

    XXH_PREFETCH_DIST ¶

    XXH_PREFETCH_DIST :: 320

    XXH_PRIME32_1 ¶

    XXH_PRIME32_1 :: 0x9E3779B1
     

    !< 0b10011110001101110111100110110001

    XXH_PRIME32_2 ¶

    XXH_PRIME32_2 :: 0x85EBCA77
     

    !< 0b10000101111010111100101001110111

    XXH_PRIME32_3 ¶

    XXH_PRIME32_3 :: 0xC2B2AE3D
     

    !< 0b11000010101100101010111000111101

    XXH_PRIME32_4 ¶

    XXH_PRIME32_4 :: 0x27D4EB2F
     

    !< 0b00100111110101001110101100101111

    XXH_PRIME32_5 ¶

    XXH_PRIME32_5 :: 0x165667B1
     

    !< 0b00010110010101100110011110110001

    XXH_PRIME64_1 ¶

    XXH_PRIME64_1 :: 0x9E3779B185EBCA87
     

    !< 0b1001111000110111011110011011000110000101111010111100101010000111

    XXH_PRIME64_2 ¶

    XXH_PRIME64_2 :: 0xC2B2AE3D27D4EB4F
     

    !< 0b1100001010110010101011100011110100100111110101001110101101001111

    XXH_PRIME64_3 ¶

    XXH_PRIME64_3 :: 0x165667B19E3779F9
     

    !< 0b0001011001010110011001111011000110011110001101110111100111111001

    XXH_PRIME64_4 ¶

    XXH_PRIME64_4 :: 0x85EBCA77C2B2AE63
     

    !< 0b1000010111101011110010100111011111000010101100101010111001100011

    XXH_PRIME64_5 ¶

    XXH_PRIME64_5 :: 0x27D4EB2F165667C5
     

    !< 0b0010011111010100111010110010111100010110010101100110011111000101

    XXH_SECRET_CONSUME_RATE ¶

    XXH_SECRET_CONSUME_RATE :: 8
     

    nb of secret bytes consumed at each accumulation

    XXH_SECRET_DEFAULT_SIZE ¶

    XXH_SECRET_DEFAULT_SIZE :: max(XXH3_SECRET_SIZE_MIN, #config(XXH_SECRET_DEFAULT_SIZE, 192))
     

    Custom secrets have a default length of 192, but can be set to a different size. The minimum secret size is 136 bytes. It must also be a multiple of 64.

    XXH_SECRET_LASTACC_START ¶

    XXH_SECRET_LASTACC_START :: 7
     

    not aligned on 8, last secret is different from acc & scrambler

    XXH_SECRET_MERGEACCS_START ¶

    XXH_SECRET_MERGEACCS_START :: 11

    XXH_STRIPE_LEN ¶

    XXH_STRIPE_LEN :: 64

    XXH_VERSION_MAJOR ¶

    XXH_VERSION_MAJOR :: 0
     

    Version definition

    XXH_VERSION_MINOR ¶

    XXH_VERSION_MINOR :: 8

    XXH_VERSION_NUMBER ¶

    XXH_VERSION_NUMBER :: XXH_VERSION_MAJOR * 100 * 100 + XXH_VERSION_MINOR * 100 + XXH_VERSION_RELEASE

    XXH_VERSION_RELEASE ¶

    XXH_VERSION_RELEASE :: 1

    Variables

    XXH3_kSecret ¶

    XXH3_kSecret: [192]u8 = …

    Procedures

    XXH128_mix32B ¶

    XXH128_mix32B :: proc(acc: u128, input_1: []u8, input_2: []u8, secret: []u8, seed: u64) -> (res: u128) {…}
     

    A bit slower than XXH3_mix16B, but handles multiply by zero better.

    XXH32 ¶

    XXH32 :: proc(input: []u8, seed: u32 = XXH32_DEFAULT_SEED) -> (digest: u32) {…}

    XXH32_avalanche ¶

    XXH32_avalanche :: proc(h32: u32) -> (res: u32) {…}
     

    Mix all bits

    XXH32_canonical_from_hash ¶

    XXH32_canonical_from_hash :: proc(hash: u32) -> (canonical: XXH32_canonical) {…}
     

    * Canonical representation *

    The default return values from XXH functions are unsigned 32 and 64 bit integers.

    The canonical representation uses big endian convention, the same convention as human-readable numbers (large digits first).

    This way, hash values can be written into a file or buffer, remaining comparable across different systems.

    The following functions allow transformation of hash values to and from their canonical format.

    XXH32_copy_state ¶

    XXH32_copy_state :: proc(dest, src: ^XXH32_state) {…}

    XXH32_create_state ¶

    XXH32_create_state :: proc(allocator := context.allocator) -> (res: ^XXH32_state, err: Error) {…}
     

    * Hash streaming *

    XXH32_destroy_state ¶

    XXH32_destroy_state :: proc(state: ^XXH32_state, allocator := context.allocator) -> (err: Error) {…}

    XXH32_digest ¶

    XXH32_digest :: proc(state: ^XXH32_state) -> (res: u32) {…}

    XXH32_endian_align ¶

    XXH32_endian_align :: proc(input: []u8, seed: u32 = XXH32_DEFAULT_SEED, alignment: Alignment) -> (res: u32) {…}

    XXH32_finalize ¶

    XXH32_finalize :: proc(h32: u32, buf: []u8, alignment: Alignment) -> (res: u32) {…}

    XXH32_hash_from_canonical ¶

    XXH32_hash_from_canonical :: proc(canonical: ^XXH32_canonical) -> (hash: u32) {…}

    XXH32_read32 ¶

    XXH32_read32 :: proc(buf: []u8, alignment: Alignment = Alignment.Unaligned) -> (res: u32) {…}

    XXH32_reset_state ¶

    XXH32_reset_state :: proc(state_ptr: ^XXH32_state, seed: u32 = XXH32_DEFAULT_SEED) -> (err: Error) {…}

    XXH32_round ¶

    XXH32_round :: proc(seed, input: u32) -> (res: u32) {…}

    XXH32_update ¶

    XXH32_update :: proc(state: ^XXH32_state, input: []u8) -> (err: Error) {…}

    XXH3_128_canonical_from_hash ¶

    XXH3_128_canonical_from_hash :: proc(hash: XXH128_hash_t) -> (canonical: XXH128_canonical) {…}

    XXH3_128_default ¶

    XXH3_128_default :: proc(input: []u8) -> (hash: u128) {…}
     

    === Public XXH128 API ===

    XXH3_128_digest ¶

    XXH3_128_digest :: proc(state: ^XXH3_state) -> (hash: u128) {…}

    XXH3_128_hash_from_canonical ¶

    XXH3_128_hash_from_canonical :: proc(src: ^XXH128_canonical) -> (hash: u128) {…}

    XXH3_128_reset ¶

    XXH3_128_reset :: proc(state: ^XXH3_state) -> (err: Error) {…}
     

    === XXH3 128-bit streaming ===

    All the functions are actually the same as for 64-bit streaming variant. The only difference is the finalization routine.

    XXH3_128_reset_with_secret ¶

    XXH3_128_reset_with_secret :: proc(state: ^XXH3_state, secret: []u8) -> (err: Error) {…}

    XXH3_128_reset_with_seed ¶

    XXH3_128_reset_with_seed :: proc(state: ^XXH3_state, seed: u64) -> (err: Error) {…}

    XXH3_128_update ¶

    XXH3_128_update :: proc(state: ^XXH3_state, input: []u8) -> (err: Error) {…}

    XXH3_128_with_secret ¶

    XXH3_128_with_secret :: proc(input: []u8, secret: []u8) -> (hash: u128) {…}

    XXH3_128_with_seed ¶

    XXH3_128_with_seed :: proc(input: []u8, seed: u64 = XXH64_DEFAULT_SEED) -> (hash: u128) {…}

    XXH3_128bits_internal ¶

    XXH3_128bits_internal :: proc(input: []u8, seed: u64, secret: []u8, f_hl128: XXH3_hashLong128_f) -> (res: u128) {…}

    XXH3_64_default ¶

    XXH3_64_default :: proc(input: []u8) -> (hash: u64) {…}
     

    === Public entry point ===

    XXH3_64_digest ¶

    XXH3_64_digest :: proc(state: ^XXH3_state) -> (hash: u64) {…}

    XXH3_64_reset ¶

    XXH3_64_reset :: XXH3_128_reset
     

    === XXH3 128-bit streaming ===

    All the functions are actually the same as for 64-bit streaming variant. The only difference is the finalization routine.

    XXH3_64_with_secret ¶

    XXH3_64_with_secret :: proc(input: []u8, secret: []u8) -> (hash: u64) {…}

    XXH3_64_with_seed ¶

    XXH3_64_with_seed :: proc(input: []u8, seed: u64 = XXH64_DEFAULT_SEED) -> (hash: u64) {…}

    XXH3_64bits_internal ¶

    XXH3_64bits_internal :: proc(input: []u8, seed: u64, secret: []u8, f_hashLong: XXH3_hashLong64_f) -> (hash: u64) {…}

    XXH3_accumulate ¶

    XXH3_accumulate :: proc(acc: []u64, input: []u8, secret: []u8, nbStripes: uint, f_acc512: XXH3_accumulate_512_f) {…}
     

    * XXH3_accumulate() * Loops over XXH3_accumulate_512(). * Assumption: nbStripes will not overflow the secret size

    XXH3_accumulate_512_scalar ¶

    XXH3_accumulate_512_scalar :: proc(acc: []u64, input: []u8, secret: []u8) {…}
     

    scalar variants - universal

    XXH3_avalanche ¶

    XXH3_avalanche :: proc(h64: u64) -> (res: u64) {…}
     

    This is a fast avalanche stage, suitable when input bits are already partially mixed

    XXH3_consume_stripes ¶

    XXH3_consume_stripes :: proc(
    	acc:               []u64, 
    	stripes_so_far:    ^uint, 
    	stripes_per_block: uint, 
    	input:             []u8, 
    	number_of_stripes: uint, 
    	secret:            []u8, 
    	secret_limit:      uint, 
    	f_acc512:          XXH3_accumulate_512_f, 
    	f_scramble:        XXH3_scramble_accumulator_f, 
    ) {…}

    XXH3_copy_state ¶

    XXH3_copy_state :: proc(dest, src: ^XXH3_state) {…}

    XXH3_create_state ¶

    XXH3_create_state :: proc(allocator := context.allocator) -> (res: ^XXH3_state, err: Error) {…}

    XXH3_destroy_state ¶

    XXH3_destroy_state :: proc(state: ^XXH3_state, allocator := context.allocator) -> (err: Error) {…}

    XXH3_digest_long ¶

    XXH3_digest_long :: proc(acc: []u64, state: ^XXH3_state, secret: []u8) {…}

    XXH3_generate_secret ¶

    XXH3_generate_secret :: proc(secret_buffer: []u8, custom_seed: []u8) {…}

    XXH3_hashLong_128b_default ¶

    XXH3_hashLong_128b_default :: proc(input: []u8, seed: u64, secret: []u8) -> (res: u128) {…}
     

    * It's important for performance that XXH3_hashLong is not inlined.

    XXH3_hashLong_128b_internal ¶

    XXH3_hashLong_128b_internal :: proc(input: []u8, secret: []u8, f_acc512: XXH3_accumulate_512_f, f_scramble: XXH3_scramble_accumulator_f) -> (res: u128) {…}

    XXH3_hashLong_128b_withSecret ¶

    XXH3_hashLong_128b_withSecret :: proc(input: []u8, seed: u64, secret: []u8) -> (res: u128) {…}
     

    * It's important for performance that XXH3_hashLong is not inlined.

    XXH3_hashLong_128b_withSeed ¶

    XXH3_hashLong_128b_withSeed :: proc(input: []u8, seed: u64, secret: []u8) -> (res: u128) {…}
     

    * It's important for performance that XXH3_hashLong is not inlined.

    XXH3_hashLong_128b_withSeed_internal ¶

    XXH3_hashLong_128b_withSeed_internal :: proc(
    	input:      []u8, 
    	seed:       u64, 
    	secret:     []u8, 
    	f_acc512:   XXH3_accumulate_512_f, 
    	f_scramble: XXH3_scramble_accumulator_f, 
    	f_initSec:  XXH3_init_custom_secret_f, 
    ) -> (res: u128) {…}

    XXH3_hashLong_64b_default ¶

    XXH3_hashLong_64b_default :: proc(input: []u8, seed64: u64, secret: []u8) -> (hash: u64) {…}
     

    It's important for performance that XXH3_hashLong is not inlined. Since the function is not inlined, the compiler may not be able to understand that, in some scenarios, its secret argument is actually a compile time constant. This variant enforces that the compiler can detect that, and uses this opportunity to streamline the generated code for better performance.

    XXH3_hashLong_64b_internal ¶

    XXH3_hashLong_64b_internal :: proc(input: []u8, secret: []u8, f_acc512: XXH3_accumulate_512_f, f_scramble: XXH3_scramble_accumulator_f) -> (hash: u64) {…}

    XXH3_hashLong_64b_withSecret ¶

    XXH3_hashLong_64b_withSecret :: proc(input: []u8, seed64: u64, secret: []u8) -> (hash: u64) {…}
     

    It's important for performance that XXH3_hashLong is not inlined.

    XXH3_hashLong_64b_withSeed ¶

    XXH3_hashLong_64b_withSeed :: proc(input: []u8, seed: u64, secret: []u8) -> (hash: u64) {…}
     

    It's important for performance that XXH3_hashLong is not inlined.

    XXH3_hashLong_64b_withSeed_internal ¶

    XXH3_hashLong_64b_withSeed_internal :: proc(input: []u8, seed: u64, f_acc512: XXH3_accumulate_512_f, f_scramble: XXH3_scramble_accumulator_f, f_init_sec: XXH3_init_custom_secret_f) -> (hash: u64) {…}
     

    XXH3_hashLong_64b_withSeed(): Generate a custom key based on alteration of default XXH3_kSecret with the seed, and then use this key for long mode hashing.

    This operation is decently fast but nonetheless costs a little bit of time. Try to avoid it whenever possible (typically when seed==0).

    It's important for performance that XXH3_hashLong is not inlined. Not sure why (uop cache maybe?), but the difference is large and easily measurable.

    XXH3_hashLong_internal_loop ¶

    XXH3_hashLong_internal_loop :: proc(acc: []u64, input: []u8, secret: []u8, f_acc512: XXH3_accumulate_512_f, f_scramble: XXH3_scramble_accumulator_f) {…}

    XXH3_init_custom_secret_scalar ¶

    XXH3_init_custom_secret_scalar :: proc(custom_secret: []u8, seed64: u64) {…}

    XXH3_init_state ¶

    XXH3_init_state :: proc(state: ^XXH3_state) {…}

    XXH3_len_0to16_128b ¶

    XXH3_len_0to16_128b :: proc(input: []u8, secret: []u8, seed: u64) -> (res: u128) {…}
     

    Assumption: secret size is >= XXH3_SECRET_SIZE_MIN

    XXH3_len_0to16_64b ¶

    XXH3_len_0to16_64b :: proc(input: []u8, secret: []u8, seed: u64) -> (res: u64) {…}

    XXH3_len_129to240_128b ¶

    XXH3_len_129to240_128b :: proc(input: []u8, secret: []u8, seed: u64) -> (res: u128) {…}

    XXH3_len_129to240_64b ¶

    XXH3_len_129to240_64b :: proc(input: []u8, secret: []u8, seed: u64) -> (res: u64) {…}

    XXH3_len_17to128_128b ¶

    XXH3_len_17to128_128b :: proc(input: []u8, secret: []u8, seed: u64) -> (res: u128) {…}

    XXH3_len_17to128_64b ¶

    XXH3_len_17to128_64b :: proc(input: []u8, secret: []u8, seed: u64) -> (res: u64) {…}
     

    For mid range keys, XXH3 uses a Mum-hash variant.

    XXH3_len_1to3_128b ¶

    XXH3_len_1to3_128b :: proc(input: []u8, secret: []u8, seed: u64) -> (res: u128) {…}

    XXH3_len_1to3_64b ¶

    XXH3_len_1to3_64b :: proc(input: []u8, secret: []u8, seed: u64) -> (res: u64) {…}
     

    At very short lengths, there isn't enough input to fully hide secrets, or use the entire secret.

    There is also only a limited amount of mixing we can do before significantly impacting performance.

    Therefore, we use different sections of the secret and always mix two secret samples with an XOR. This should have no effect on performance on the seedless or withSeed variants because everything _should_ be constant folded by modern compilers.

    The XOR mixing hides individual parts of the secret and increases entropy. This adds an extra layer of strength for custom secrets.

    XXH3_len_4to8_128b ¶

    XXH3_len_4to8_128b :: proc(input: []u8, secret: []u8, seed: u64) -> (res: u128) {…}

    XXH3_len_4to8_64b ¶

    XXH3_len_4to8_64b :: proc(input: []u8, secret: []u8, seed: u64) -> (res: u64) {…}

    XXH3_len_9to16_128b ¶

    XXH3_len_9to16_128b :: proc(input: []u8, secret: []u8, seed: u64) -> (res: u128) {…}

    XXH3_len_9to16_64b ¶

    XXH3_len_9to16_64b :: proc(input: []u8, secret: []u8, seed: u64) -> (res: u64) {…}

    XXH3_mergeAccs ¶

    XXH3_mergeAccs :: proc(acc: []u64, secret: []u8, start: u64) -> (res: u64) {…}

    XXH3_mix16B ¶

    XXH3_mix16B :: proc(input: []u8, secret: []u8, seed: u64) -> (res: u64) {…}
     

    DISCLAIMER: There are known seed-dependent multicollisions here due to multiplication by zero, affecting hashes of lengths 17 to 240.

    However, they are very unlikely.

    Keep this in mind when using the unseeded XXH3_64bits() variant: As with all unseeded non-cryptographic hashes, it does not attempt to defend itself against specially crafted inputs, only random inputs.

    Compared to classic UMAC where a 1 in 2^31 chance of 4 consecutive bytes cancelling out the secret is taken an arbitrary number of times (addressed in XXH3_accumulate_512), this collision is very unlikely with random inputs and/or proper seeding:

    This only has a 1 in 2^63 chance of 8 consecutive bytes cancelling out, in a function that is only called up to 16 times per hash with up to 240 bytes of input.

    This is not too bad for a non-cryptographic hash function, especially with only 64 bit outputs.

    The 128-bit variant (which trades some speed for strength) is NOT affected by this, although it is always a good idea to use a proper seed if you care about strength.

    XXH3_mix2Accs ¶

    XXH3_mix2Accs :: proc(acc: []u64, secret: []u8) -> (res: u64) {…}

    XXH3_reset_internal ¶

    XXH3_reset_internal :: proc(state: ^XXH3_state, seed: u64, secret: []u8, secret_size: uint) {…}

    XXH3_rrmxmx ¶

    XXH3_rrmxmx :: proc(h64, length: u64) -> (res: u64) {…}
     

    This is a stronger avalanche, inspired by Pelle Evensen's rrmxmx preferable when input has not been previously mixed

    XXH3_scramble_accumulator_scalar ¶

    XXH3_scramble_accumulator_scalar :: proc(acc: []u64, secret: []u8) {…}

    XXH3_update ¶

    XXH3_update :: proc(state: ^XXH3_state, input: []u8, f_acc512: XXH3_accumulate_512_f, f_scramble: XXH3_scramble_accumulator_f) -> (err: Error) {…}
     

    Both XXH3_64bits_update and XXH3_128bits_update use this routine.

    XXH64 ¶

    XXH64 :: proc(input: []u8, seed: u64 = XXH64_DEFAULT_SEED) -> (digest: u64) {…}

    XXH64_avalanche ¶

    XXH64_avalanche :: proc(h64: u64) -> (res: u64) {…}

    XXH64_canonical_from_hash ¶

    XXH64_canonical_from_hash :: proc(hash: u64) -> (canonical: XXH64_canonical) {…}
     

    * Canonical representation *

    The default return values from XXH functions are unsigned 32 and 64 bit integers.

    The canonical representation uses big endian convention, the same convention as human-readable numbers (large digits first).

    This way, hash values can be written into a file or buffer, remaining comparable across different systems.

    The following functions allow transformation of hash values to and from their canonical format.

    XXH64_copy_state ¶

    XXH64_copy_state :: proc(dest, src: ^XXH64_state) {…}

    XXH64_create_state ¶

    XXH64_create_state :: proc(allocator := context.allocator) -> (res: ^XXH64_state, err: Error) {…}
     

    * Hash Streaming *

    XXH64_destroy_state ¶

    XXH64_destroy_state :: proc(state: ^XXH64_state, allocator := context.allocator) -> (err: Error) {…}

    XXH64_digest ¶

    XXH64_digest :: proc(state: ^XXH64_state) -> (res: u64) {…}

    XXH64_endian_align ¶

    XXH64_endian_align :: proc(input: []u8, seed: u64 = XXH64_DEFAULT_SEED, alignment: Alignment = Alignment.Unaligned) -> (res: u64) {…}

    XXH64_finalize ¶

    XXH64_finalize :: proc(h64: u64, buf: []u8, alignment: Alignment) -> (res: u64) {…}

    XXH64_hash_from_canonical ¶

    XXH64_hash_from_canonical :: proc(canonical: ^XXH64_canonical) -> (hash: u64) {…}

    XXH64_mergeRound ¶

    XXH64_mergeRound :: proc(acc, val: u64) -> (res: u64) {…}

    XXH64_read64 ¶

    XXH64_read64 :: proc(buf: []u8, alignment: Alignment = Alignment.Unaligned) -> (res: u64) {…}

    XXH64_reset_state ¶

    XXH64_reset_state :: proc(state_ptr: ^XXH64_state, seed: u64 = XXH64_DEFAULT_SEED) -> (err: Error) {…}

    XXH64_round ¶

    XXH64_round :: proc(acc, input: u64) -> (res: u64) {…}

    XXH64_update ¶

    XXH64_update :: proc(state: ^XXH64_state, input: []u8) -> (err: Error) {…}

    XXH_mul_64_to_128_fold_64 ¶

    XXH_mul_64_to_128_fold_64 :: proc(lhs, rhs: u64) -> (res: u64) {…}
     

    The reason for the separate function is to prevent passing too many structs around by value. This will hopefully inline the multiply, but we don't force it.

    @param lhs, rhs The 64-bit integers to multiply @return The low 64 bits of the product XOR'd by the high 64 bits.

    XXH_rotl32 ¶

    XXH_rotl32 :: proc(x, r: u32) -> (res: u32) {…}

    XXH_rotl64 ¶

    XXH_rotl64 :: proc(x, r: u64) -> (res: u64) {…}

    XXH_writeLE64 ¶

    XXH_writeLE64 :: proc(dst: []u8, v64: u64le) {…}

    XXH_xorshift_64 ¶

    XXH_xorshift_64 :: proc(v: u64, #any_int shift: uint) -> (res: u64) {…}

    byte_swap ¶

    byte_swap :: intrinsics.byte_swap

    prefetch_address ¶

    prefetch_address :: proc(address: rawptr) {…}

    prefetch_offset ¶

    prefetch_offset :: proc(address: rawptr, #any_int offset: uintptr) {…}

    Procedure Groups

    Source Files

    Generation Information

    Generated with odin version dev-2024-12 (vendor "odin") Windows_amd64 @ 2024-12-17 21:11:00.986609300 +0000 UTC