1
//! Minimal CRC-32 (IEEE 802.3 / gzip / PNG polynomial).
2
//!
3
//! Used by the variable-font PostScript-name generator to produce the
4
//! "last resort" hashed suffix described in the OpenType specification's
5
//! *Generating PostScript names for OpenType Font Variations* section,
6
//! which calls for the IEEE 802.3 CRC-32. This is not on a hot path —
7
//! it only runs when a generated PostScript name exceeds 63 characters —
8
//! so a simple bitwise implementation is preferred over pulling in a
9
//! dedicated CRC-32 crate.
10

            
11
const POLY: u32 = 0xEDB88320;
12

            
13
pub fn hash(bytes: &[u8]) -> u32 {
14
    let mut crc: u32 = !0;
15
    for &byte in bytes {
16
        crc ^= u32::from(byte);
17
        for _ in 0..8 {
18
            let mask = (crc & 1).wrapping_neg();
19
            crc = (crc >> 1) ^ (POLY & mask);
20
        }
21
    }
22
    !crc
23
}
24

            
25
#[cfg(test)]
26
mod tests {
27
    use super::hash;
28

            
29
    // Reference values from the standard IEEE 802.3 CRC-32 (gzip / PNG).
30
    #[test]
31
    fn empty() {
32
        assert_eq!(hash(b""), 0);
33
    }
34

            
35
    #[test]
36
    fn ascii() {
37
        // "123456789" has the well-known check value 0xCBF43926.
38
        assert_eq!(hash(b"123456789"), 0xCBF43926);
39
    }
40

            
41
    #[test]
42
    fn short() {
43
        assert_eq!(hash(b"a"), 0xE8B7BE43);
44
    }
45
}