Skip to content
CryoCryo home
Stdlibcore

hash

import std::core::hash; · source

A Hash type feeds its bytes to a Hasher, which folds them into a running state and finally produces a u64.

import std::core::hash;

mut h: DefaultHasher = DefaultHasher::new();
h.fold(user_id);
h.fold(name);
const digest: u64 = h.finish();

Hasher

type trait Hasher {
    write_u8(mut &this, value: u8) -> void;
    write_bytes(mut &this, bytes: Slice<u8>) -> void;
    write_uint(mut &this, value: u128, byte_count: u32) -> void;
    fold<T>(mut &this, value: T) -> void;
    finish(&this) -> u64;
}

write_u8 is the one required method; write_bytes, write_uint, and fold have defaults built on it.

fold<T> is the composition entry point: it dispatches at compile time via static match (T) — no runtime cost and no trait bound, because the arms are the accepted types. It takes every primitive scalar, folding integers at their natural width (little-endian), floats as their IEEE bit pattern, char as its 32-bit scalar, boolean as one byte, and string as its bytes plus a separator NUL so that "ab" + "c" cannot collide with "a" + "bc". Anything non-primitive is a compile error.

Implementors

implement trait Hasher for struct DefaultHasher

implement trait Hasher for struct Fnv128Hasher

Hash

type trait Hash {
    hash<H>(&this, hasher: mut &H) -> void
    where H: Hasher;
}

A type that can feed itself to any Hasher. Floats have no impl: their Eq is bitwise, and hashing the bits is a one-liner with fold when you need it.

Implementors

implement trait Hash for u8

implement trait Hash for u16

implement trait Hash for u32

implement trait Hash for u64

implement trait Hash for i8

implement trait Hash for i16

implement trait Hash for i32

implement trait Hash for i64

implement trait Hash for u128

implement trait Hash for i128

implement trait Hash for usize

implement trait Hash for isize

implement trait Hash for boolean

implement trait Hash for char

implement trait Hash for string

implement<T, A> trait Hash for struct Array<T, A>
where T: Hash, A: Allocator   // std::collections::array

implement trait Hash for struct Str   // std::collections::str

implement<A> trait Hash for struct String<A>
where A: Allocator   // std::collections::string

DefaultHasher

type struct DefaultHasher {
    state: u64;

    static new() -> DefaultHasher;
    static from_state(state: u64) -> DefaultHasher;
    static offset_basis() -> u64;
}

64-bit FNV-1a. Fast and simple, and the right default for HashMap keys when the inputs are trusted. It is not DoS-resistant on its own; HashMap hardens it with a per-map seed. from_state lets you resume from a previously finished digest and thread a running hash through several steps.

Fnv128Hasher

type struct Fnv128Hasher {
    state: u128;

    static new() -> Fnv128Hasher;
    static from_state(state: u128) -> Fnv128Hasher;
    finish128(&this) -> u128;
    high64(&this) -> u64;
    low64(&this) -> u64;
}

The same construction at twice the width, for cases where a collision is a correctness failure rather than a slow bucket. finish128() gives the full digest; high64() and low64() split it for rendering; finish() from the Hasher trait folds it to 64 bits. Still FNV, so still not hardened — this is width, not security.

digest

function digest<T>(value: &T) -> u64
where T: Hash;

The one-shot form: a fresh DefaultHasher, one hash, one finish.