DoxigAlpha

int

Integer-to-integer hashing for bit widths <= 256.

Function parameters

Parameters

#
input:anytype

Type definitions in this namespace

Types

#

Functions in this namespace

Functions

#
int
Integer-to-integer hashing for bit widths <= 256.

Source

Implementation

#
pub fn int(input: anytype) @TypeOf(input) {
    // This function is only intended for integer types
    const info = @typeInfo(@TypeOf(input)).int;
    const bits = info.bits;
    // Convert input to unsigned integer (easier to deal with)
    const Uint = @Type(.{ .int = .{ .bits = bits, .signedness = .unsigned } });
    const u_input: Uint = @bitCast(input);
    if (bits > 256) @compileError("bit widths > 256 are unsupported, use std.hash.autoHash functionality.");
    // For bit widths that don't have a dedicated function, use a heuristic
    // construction with a multiplier suited to diffusion -
    // a mod 2^bits where a^2 - 46 * a + 1 = 0 mod 2^(bits + 4),
    // on Mathematica: bits = 256; BaseForm[Solve[1 - 46 a + a^2 == 0, a, Modulus -> 2^(bits + 4)][[-1]][[1]][[2]], 16]
    const mult: Uint = @truncate(0xfac2e27ed2036860a062b5f264d80a512b00aa459b448bf1eca24d41c96f59e5b);
    // The bit width of the input integer determines how to hash it
    const output = switch (bits) {
        0...2 => u_input *% mult,
        16 => uint16(u_input),
        32 => uint32(u_input),
        64 => uint64(u_input),
        else => blk: {
            var x: Uint = u_input;
            inline for (0..4) |_| {
                x ^= x >> (bits / 2);
                x *%= mult;
            }
            break :blk x;
        },
    };
    return @bitCast(output);
}