hash

tape
import hash from "hash";

hash turns bytes or integers into well-spread numbers: for hash maps, checksums and quick equality checks. Every function gives the same result on every platform, in the VM and natively, and the byte hashes match their published reference implementations.

None of these hashes resists an attacker who picks the input. Don’t use them for passwords, signatures or anything security-related.

The module is pure and works in every profile, t0 included.

Functions

fnv1a_64

tape
pub fn fnv1a_64(data: []const u8) -> u64

64-bit FNV-1a. Tiny and simple; good for short keys.

tape
let h: u64 = hash.fnv1a_64("hello");
io.println("{h}");      // 11831194018420276491

wyhash

tape
pub fn wyhash(data: []const u8, seed: u64) -> u64

wyhash: fast on any length and well mixed, the one to pick for hash tables. Different seeds give unrelated hashes. The result is the same as the reference wyhash.h (final version 4.2) with its default secret.

tape
const BUCKETS: u64 = 64;

fn bucket_of(key: []const u8) -> i64 {
    return (hash.wyhash(key, 0) % BUCKETS) as i64;
}

io.println("{hash.wyhash("hello", 0)}");    // 5306810434294928543
io.println("{bucket_of("alice")}");         // 40

crc32

tape
pub fn crc32(data: []const u8) -> u32

CRC-32 as used by zip, gzip and PNG (IEEE 802.3).

tape
io.println("{hash.crc32("123456789") == 0xCBF43926}");   // true

crc32_update

tape
pub fn crc32_update(crc: u32, data: []const u8) -> u32

Continues a CRC-32 over more bytes, for data that arrives in pieces. Start from 0; the result after the last piece is the CRC-32 of all of it.

tape
var crc: u32 = 0;
crc = hash.crc32_update(crc, "1234");
crc = hash.crc32_update(crc, "56789");
io.println("{crc == hash.crc32("123456789")}");   // true

hash_i64

tape
pub fn hash_i64(v: i64) -> u64

Mixes an integer into a well-spread u64, for putting integer keys in hash map buckets. Neighbouring keys land far apart, and no two keys give the same result. It is the SplitMix64 step.

tape
let idx: u64 = hash.hash_i64(42) & 63;   // bucket 21 of 64
io.println("{hash.hash_i64(0)}");         // 16294208416658607535

Last modified: