commit cb5fb46373cc085459dcc3658b53c49f4186eaca Author: mehbark Date: Thu Apr 17 10:31:10 2025 -0400 initial bruteforce attempt diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..05085de --- /dev/null +++ b/Cargo.lock @@ -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" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..4d8cc7f --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "capitalization-collision" +version = "0.1.0" +edition = "2024" + +[dependencies] +sha1 = "0.10.6" diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..9257d75 --- /dev/null +++ b/src/main.rs @@ -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(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 { + 0..(2u64.pow(options)) +}