First commit. The hashes and their inverses.
This commit is contained in:
commit
62138fd9a4
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
/target
|
||||
/Cargo.lock
|
8
Cargo.toml
Normal file
8
Cargo.toml
Normal file
|
@ -0,0 +1,8 @@
|
|||
[package]
|
||||
name = "bit_mixers"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
101
src/lib.rs
Normal file
101
src/lib.rs
Normal file
|
@ -0,0 +1,101 @@
|
|||
/// 32-bit bijective bit mixer.
|
||||
///
|
||||
/// https://github.com/skeeto/hash-prospector
|
||||
pub fn mix32(mut n: u32) -> u32 {
|
||||
n ^= n >> 16;
|
||||
n = n.wrapping_mul(0x21f0aaad);
|
||||
n ^= n >> 15;
|
||||
n = n.wrapping_mul(0xd35a2d97);
|
||||
n ^= n >> 15;
|
||||
|
||||
n
|
||||
}
|
||||
|
||||
/// Inverse of `mix32()`.
|
||||
pub fn mix32_inv(mut n: u32) -> u32 {
|
||||
n ^= (n >> 15) ^ (n >> 30);
|
||||
n = n.wrapping_mul(0x37132227);
|
||||
n ^= (n >> 15) ^ (n >> 30);
|
||||
n = n.wrapping_mul(0x333c4925);
|
||||
n ^= n >> 16;
|
||||
|
||||
n
|
||||
}
|
||||
|
||||
/// 64-bit bijective bit mixer.
|
||||
///
|
||||
/// http://zimbry.blogspot.ch/2011/09/better-bit-mixing-improving-on.html
|
||||
pub fn mix64(mut n: u64) -> u64 {
|
||||
n ^= n >> 31;
|
||||
n = n.wrapping_mul(0x7fb5d329728ea185);
|
||||
n ^= n >> 27;
|
||||
n = n.wrapping_mul(0x81dadef4bc2dd44d);
|
||||
n ^= n >> 33;
|
||||
|
||||
n
|
||||
}
|
||||
|
||||
/// Inverse of `mix64()`.
|
||||
pub fn mix64_inv(mut n: u64) -> u64 {
|
||||
n ^= n >> 33;
|
||||
n = n.wrapping_mul(0x4d6dff26c61d8485);
|
||||
n ^= (n >> 27) ^ (n >> 54);
|
||||
n = n.wrapping_mul(0x4c5ff4596f4a2f4d);
|
||||
n ^= (n >> 31) ^ (n >> 62);
|
||||
|
||||
n
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
// fn compute_multiplicative_inverse_32(a: u32) -> u32 {
|
||||
// assert!(a & 1 == 1);
|
||||
// let mut x = a;
|
||||
// // Overkill iteration count.
|
||||
// for _ in 0..100 {
|
||||
// // x += x - a * x * x;
|
||||
// x = x.wrapping_add(x.wrapping_sub(a.wrapping_mul(x).wrapping_mul(x)));
|
||||
// }
|
||||
|
||||
// x
|
||||
// }
|
||||
|
||||
// fn compute_multiplicative_inverse_64(a: u64) -> u64 {
|
||||
// assert!(a & 1 == 1);
|
||||
// let mut x = a;
|
||||
// // Overkill iteration count.
|
||||
// for _ in 0..100 {
|
||||
// // x += x - a * x * x;
|
||||
// x = x.wrapping_add(x.wrapping_sub(a.wrapping_mul(x).wrapping_mul(x)));
|
||||
// }
|
||||
|
||||
// x
|
||||
// }
|
||||
|
||||
// #[test]
|
||||
// fn get_inverse() {
|
||||
// // Panic, to print the result.
|
||||
// panic!("0x{:x}", compute_multiplicative_inverse_32(0x21f0aaad));
|
||||
// panic!("0x{:x}", compute_multiplicative_inverse_32(0xd35a2d97));
|
||||
// }
|
||||
|
||||
#[test]
|
||||
fn mix32_invertability() {
|
||||
for i in 0..9999999u32 {
|
||||
let n = mix32(mix32(mix32(i)));
|
||||
assert_eq!(n, mix32_inv(mix32(n)));
|
||||
assert_eq!(n, mix32(mix32_inv(n)));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mix64_invertability() {
|
||||
for i in 0..9999999u64 {
|
||||
let n = mix64(mix64(mix64(i)));
|
||||
assert_eq!(n, mix64_inv(mix64(n)));
|
||||
assert_eq!(n, mix64(mix64_inv(n)));
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user