Hamming Distance Over Bytes
Count differing bits between equal-length byte slices, report bit similarity, and reject inputs of unequal length.
Code
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());
}Report a problem with this exampleOpens a pre-filled issue on GitHub.