Hamming Distance Over Bytes

Count differing bits between equal-length byte slices, report bit similarity, and reject inputs of unequal length.

RustData Integrity

Code

snippet
fn hamming_distance(left: &[u8], right: &[u8]) -> Result<u32, String> {
    if left.len() != right.len() {
        return Err(format!(
            "inputs must match in length: {} vs {}",
            left.len(),
            right.len()
        ));
    }
    Ok(left
        .iter()
        .zip(right.iter())
        .map(|(a, b)| (a ^ b).count_ones())
        .sum())
}

fn hamming_distance_bits(left: u64, right: u64) -> u32 {
    (left ^ right).count_ones()
}

fn similarity(left: &[u8], right: &[u8]) -> Result<f64, String> {
    if left.is_empty() {
        return Err("inputs must not be empty".to_string());
    }
    let distance = hamming_distance(left, right)?;
    let total_bits = (left.len() * 8) as f64;
    Ok(1.0 - f64::from(distance) / total_bits)
}

fn main() {
    let left = b"karolin";
    let right = b"kathrin";
    println!("distance: {:?}", hamming_distance(left, right));
    println!("similarity: {:.4}", similarity(left, right).unwrap_or(0.0));
    println!("bits: {}", hamming_distance_bits(0b1011, 0b1001));
    println!("length mismatch: {}", hamming_distance(b"abc", b"ab").is_err());
}