#[inline]
#[must_use]
pub fn hamming_distance_slice(a: &[u8], b: &[u8]) -> u32 {
assert_eq!(a.len(), b.len(), "Slice lengths must match");
let mut distance = 0u32;
for i in 0..a.len() {
let xor = a[i] ^ b[i];
distance += xor.count_ones();
}
distance
}
#[inline]
#[must_use]
pub fn hamming_distance_portable(a: &[u8; 96], b: &[u8; 96]) -> u32 {
let mut distance = 0u32;
for i in 0..96 {
let xor = a[i] ^ b[i];
distance += xor.count_ones();
}
distance
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_portable_identical() {
let a = [0xAA; 96];
let b = [0xAA; 96];
assert_eq!(hamming_distance_portable(&a, &b), 0);
}
#[test]
fn test_portable_opposite() {
let a = [0x00; 96];
let b = [0xFF; 96];
assert_eq!(hamming_distance_portable(&a, &b), 768);
}
#[test]
fn test_portable_alternating() {
let a = [0xAA; 96]; let b = [0x55; 96]; assert_eq!(hamming_distance_portable(&a, &b), 768);
}
#[test]
fn test_portable_half_bits() {
let a = [0xF0; 96]; let b = [0x0F; 96]; assert_eq!(hamming_distance_portable(&a, &b), 768);
}
#[test]
fn test_portable_single_bit() {
let mut a = [0x00; 96];
let b = [0x00; 96];
a[0] = 0x01;
assert_eq!(hamming_distance_portable(&a, &b), 1);
}
#[test]
fn test_portable_bounds() {
let a = [0xFF; 96];
let b = [0x00; 96];
let distance = hamming_distance_portable(&a, &b);
assert!(distance <= 768);
assert_eq!(distance, 768);
}
#[test]
fn test_slice_empty() {
let a: Vec<u8> = vec![];
let b: Vec<u8> = vec![];
assert_eq!(hamming_distance_slice(&a, &b), 0);
}
#[test]
fn test_slice_single_byte() {
let a = vec![0xFF];
let b = vec![0x00];
assert_eq!(hamming_distance_slice(&a, &b), 8);
}
#[test]
fn test_slice_15_bytes() {
let a = vec![0xFF; 15];
let b = vec![0x00; 15];
assert_eq!(hamming_distance_slice(&a, &b), 120); }
#[test]
fn test_slice_16_bytes() {
let a = vec![0xFF; 16];
let b = vec![0x00; 16];
assert_eq!(hamming_distance_slice(&a, &b), 128); }
#[test]
fn test_slice_17_bytes() {
let a = vec![0xFF; 17];
let b = vec![0x00; 17];
assert_eq!(hamming_distance_slice(&a, &b), 136); }
#[test]
fn test_slice_matches_portable_96() {
let a = [0xAA; 96];
let b = [0x55; 96];
assert_eq!(
hamming_distance_slice(&a, &b),
hamming_distance_portable(&a, &b)
);
}
}