initial bruteforce attempt
This commit is contained in:
commit
cb5fb46373
3 changed files with 150 additions and 0 deletions
93
Cargo.lock
generated
Normal file
93
Cargo.lock
generated
Normal file
|
@ -0,0 +1,93 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "capitalization-collision"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"sha1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.172"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
|
||||
|
||||
[[package]]
|
||||
name = "sha1"
|
||||
version = "0.10.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
7
Cargo.toml
Normal file
7
Cargo.toml
Normal file
|
@ -0,0 +1,7 @@
|
|||
[package]
|
||||
name = "capitalization-collision"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
sha1 = "0.10.6"
|
50
src/main.rs
Normal file
50
src/main.rs
Normal file
|
@ -0,0 +1,50 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use sha1::{Digest, Sha1};
|
||||
fn main() {
|
||||
let src = b"the purple cow is prancing along";
|
||||
let prefix_length = 7;
|
||||
|
||||
let alpha_count = src.iter().filter(|b| b.is_ascii_alphabetic()).count() as u32;
|
||||
assert!(alpha_count <= 64);
|
||||
|
||||
let permutation_count = 2usize.pow(alpha_count);
|
||||
let mut hashes = HashMap::new();
|
||||
|
||||
for upper_mask in perm_masks(alpha_count) {
|
||||
if upper_mask % 100_000 == 0 {
|
||||
eprintln!("{upper_mask}/{permutation_count}");
|
||||
};
|
||||
let capitalized = apply_capitalization_mask(src, upper_mask);
|
||||
let digest = Sha1::digest(capitalized);
|
||||
let prefix = &digest[..prefix_length];
|
||||
if let Some(other_mask) = hashes.get(prefix) {
|
||||
let other = apply_capitalization_mask(src, *other_mask);
|
||||
println!(
|
||||
"{}\n{}\n",
|
||||
String::from_utf8_lossy(&capitalized),
|
||||
String::from_utf8_lossy(&other)
|
||||
);
|
||||
}
|
||||
hashes.insert(prefix.to_owned(), upper_mask);
|
||||
}
|
||||
}
|
||||
|
||||
fn apply_capitalization_mask<const N: usize>(bytes: &[u8; N], mut upper_mask: u64) -> [u8; N] {
|
||||
let mut new = *bytes;
|
||||
for i in 0..N {
|
||||
if bytes[i].is_ascii_alphabetic() {
|
||||
new[i] = if upper_mask & 1 == 1 {
|
||||
bytes[i].to_ascii_uppercase()
|
||||
} else {
|
||||
bytes[i].to_ascii_lowercase()
|
||||
};
|
||||
upper_mask >>= 1;
|
||||
}
|
||||
}
|
||||
new
|
||||
}
|
||||
|
||||
fn perm_masks(options: u32) -> impl Iterator<Item = u64> {
|
||||
0..(2u64.pow(options))
|
||||
}
|
Loading…
Reference in a new issue