diff -r 278533359a93 -r 5febd2bc5372 rust/hedgewars-server/src/core/digest.rs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rust/hedgewars-server/src/core/digest.rs Sat Feb 22 19:39:31 2025 +0300 @@ -0,0 +1,55 @@ +use rand::{thread_rng, RngCore}; +use std::fmt::{Formatter, LowerHex}; + +#[derive(PartialEq, Debug)] +pub struct Sha1Digest([u8; 20]); + +impl Sha1Digest { + pub fn new(digest: [u8; 20]) -> Self { + Self(digest) + } + + pub fn random() -> Self { + let mut result = Sha1Digest(Default::default()); + thread_rng().fill_bytes(&mut result.0); + result + } +} + +impl LowerHex for Sha1Digest { + fn fmt(&self, f: &mut Formatter) -> Result<(), std::fmt::Error> { + for byte in &self.0 { + write!(f, "{:02x}", byte)?; + } + Ok(()) + } +} + +impl PartialEq<&str> for Sha1Digest { + fn eq(&self, other: &&str) -> bool { + if other.len() != self.0.len() * 2 { + false + } else { + #[inline] + fn convert(c: u8) -> u8 { + if c > b'9' { + c.wrapping_sub(b'a').saturating_add(10) + } else { + c.wrapping_sub(b'0') + } + } + + other + .as_bytes() + .chunks_exact(2) + .zip(&self.0) + .all(|(chars, byte)| { + if let [hi, lo] = chars { + convert(*lo) == byte & 0x0f && convert(*hi) == (byte & 0xf0) >> 4 + } else { + unreachable!() + } + }) + } + } +}