webrisk_hash 0.1.0

URL canonicalization and hashing for Google Web Risk API
Documentation
use webrisk_hash::truncated_sha256_prefix;

#[test]
fn fips_180_2_example_b1_32_bits() {
    let out = truncated_sha256_prefix("abc", 32);
    assert_eq!(out.len(), 4);
    assert_eq!(out, vec![0xba, 0x78, 0x16, 0xbf]);
}

#[test]
fn fips_180_2_example_b2_48_bits() {
    let input = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
    let out = truncated_sha256_prefix(input, 48);
    assert_eq!(out.len(), 6);
    assert_eq!(out, vec![0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06]);
}

#[test]
fn fips_180_2_example_b3_96_bits_million_as() {
    let input: String = "a".repeat(1_000_000);
    let out = truncated_sha256_prefix(&input, 96);
    assert_eq!(out.len(), 12);
    assert_eq!(
        out,
        vec![0xcd, 0xc7, 0x6e, 0x5c, 0x99, 0x14, 0xfb, 0x92, 0x81, 0xa1, 0xc7, 0xe2]
    );
}

#[test]
fn returns_empty_for_zero_bits() {
    let out = truncated_sha256_prefix("abc", 0);
    assert_eq!(out.len(), 0);
    assert!(out.is_empty());
}

#[test]
fn handles_non_multiple_of_8_bits() {
    // 20 bits -> 2 bytes (integer division)
    let out = truncated_sha256_prefix("abc", 20);
    assert_eq!(out.len(), 2);
}

#[test]
fn clamps_bits_above_256_to_full_hash() {
    // bits > 256 should not panic, returns full 32-byte hash
    let out = truncated_sha256_prefix("abc", 512);
    assert_eq!(out.len(), 32);
}