extern crate alloc;
#[must_use]
pub fn rpc_member_hash(name: &str) -> u32 {
let digest = md5_first4(name.as_bytes());
u32::from_le_bytes(digest)
}
fn md5_first4(bytes: &[u8]) -> [u8; 4] {
let full = zerodds_types::hash::hash_bytes(bytes);
[full.0[0], full.0[1], full.0[2], full.0[3]]
}
#[cfg(test)]
#[allow(clippy::expect_used)]
mod tests {
use super::*;
#[test]
fn rpc_hash_is_md5_first_4_bytes_le_u32() {
let h1 = rpc_member_hash("getName");
let h2 = rpc_member_hash("getName");
assert_eq!(h1, h2, "Hash muss deterministisch sein");
}
#[test]
fn rpc_hash_distinct_for_different_names() {
let h1 = rpc_member_hash("getName");
let h2 = rpc_member_hash("setName");
assert_ne!(h1, h2);
}
#[test]
fn rpc_hash_empty_string_is_md5_empty_first_4_bytes() {
let h = rpc_member_hash("");
assert_eq!(h, 0xd98c_1dd4);
}
#[test]
fn rpc_hash_uses_first_4_bytes_not_last() {
let h = rpc_member_hash("a");
assert_eq!(h, 0xb975_c10c);
}
}