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();

Types

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.

Methods

write_u8(mut &this, value: u8) -> void;

Feed a single byte into the hash state.

write_bytes(mut &this, bytes: Slice<u8>) -> void;

Feed a byte slice. Implementations should override with a faster bulk path; the default falls back to write_u8 per byte.

write_uint(mut &this, value: u128, byte_count: u32) -> void;

Feed the low byte_count bytes of value, least-significant byte first (little-endian, platform-independent). The single entry point for hashing any fixed-width integer: write_u8 is the 1-byte special case; this covers 2/4/8/16-byte values. The default loops write_u8; implementations may override with a faster path.

fold<T>(mut &this, value: T) -> void;

Fold one delimited value into the running digest, dispatched at compile time via static match (T) (no runtime cost, no trait bound - the arms ARE the accepted types). Lets a digest be composed from heterogeneous typed parts (h.fold(x); h.fold(y); h.finish()) without a per-type helper name. Every primitive scalar is accepted: - integers (u8..u128, i8..i128, usize/isize) - their two's-complement bytes at NATURAL width, low byte first (LE), so a u8 folds 1 byte, a u32 4, a u64 8, a u128 16. - f32/f64 - their IEEE-754 bit pattern (via mem::transmute), so 0.0/-0.0/

finish(&this) -> u64;

Finalize the hash and return the digest. After calling finish the hasher should not be written to again.

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.

Methods

hash<H>(&this, hasher: mut &H) -> void where H: Hasher;

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.

Properties

PropertyType
stateu64

Constructors

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

Resume hashing from a previously-finished u64 state. Lets an incremental fold thread a running digest through several steps (e.g. build fingerprinting) without re-deriving the FNV-1a update inline.

Static functions

static offset_basis() -> u64;

The FNV-1a offset basis: the initial state of a fresh hasher.

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.

Properties

PropertyType
stateu128

Constructors

static new() -> Fnv128Hasher;
static from_state(state: u128) -> Fnv128Hasher;

Resume from a previously-finish128ed state, so a digest can be threaded through several steps without re-deriving the update.

Methods

finish128(&this) -> u128;

The full 128-bit digest. finish narrows to 64 bits to satisfy Hasher; callers that want the width this type exists for use this.

high64(&this) -> u64;

The digest's two halves, high first, for callers rendering it as text. Returned rather than formatted here so core::hash keeps depending on nothing but core - hex formatting lives on u64, and pulling String in for it would put the collections module underneath every HashMap that uses this file.

low64(&this) -> u64;

Free Functions

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

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

Constants

const FNV_PRIME:           u64  = 1099511628211;
const FNV_OFFSET_BASIS:    u64  = 14695981039346656037;
const FNV128_PRIME:        u128 = 309485009821345068724781371;
const FNV128_OFFSET_BASIS: u128 = 144066263297769815596495629667062367629;