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