use sha2::{Digest, Sha256}; use std::time; use std::collections::HashMap; use threadpool::ThreadPool; fn main() { let hash = "2e9352c704043c75fa1c2a424fce7bef0569ec08af453e841101596d911d26e3".to_string(); let length = 4; crack_password_parallel(hash, length); } fn crack_password_parallel(crypto_hash: String, length: u32) { let num_cores = num_cpus::get() as u32; let chunks = get_chunks(num_cores, length); let pool = ThreadPool::new(num_cores as usize); println!("{:?}", chunks); for (chunk_start, chunk_end) in chunks { let hash = crypto_hash.clone(); pool.execute(move|| { println!("{}:{}", chunk_start, chunk_end); let combinations = get_chunk_combinations(length, chunk_start, chunk_end); for combination in combinations { if check_password(&hash, combination.clone()) { println!("PASSWORD CRACKED:{}", combination); break; } } }); } pool.join(); } fn get_chunk_combinations(length: u32, min_number: u32, max_number: u32) -> Vec<String> { let mut combinations: Vec<String> = Vec::new(); for i in min_number..max_number { let str_num: String = i.to_string(); let zeros: String = "0".repeat((length - str_num.chars().count() as u32).try_into().unwrap()); combinations.push(format!("{}{}", zeros, str_num)); } return combinations; } fn get_chunks(num_ranges: u32, length: u32) -> HashMap<u32, u32>{ let max_number = 10_i32.pow(length) as u32; let mut chunk_starts = Vec::new(); for i in 0..num_ranges { chunk_starts.push(max_number / num_ranges * i ) } let mut chunk_ends = Vec::new(); for i in &chunk_starts[1..] { chunk_ends.push(i - 1); } chunk_ends.push(max_number); let mut chunks:HashMap<u32, u32> = HashMap::new(); for i in 0..chunk_starts.len() { chunks.insert(chunk_starts[i], chunk_ends[i]); } return chunks } fn get_combinations(length: u32) -> Vec<String> { let mut combinations: Vec<String> = Vec::new(); let min_number = 0; let max_number = 10_i32.pow(length); for i in min_number..max_number { let str_num: String = i.to_string(); let zeros: String = "0".repeat((length - str_num.chars().count() as u32).try_into().unwrap()); combinations.push(format!("{}{}", zeros, str_num)); } return combinations; } fn get_crypto_hash(password: String) -> String { let sha = Sha256::digest(password); hex::encode(sha).to_string() } fn check_password(expected_crypto_hash: &String, possible_password: String) -> bool { let actual_crypto_hash = get_crypto_hash(possible_password); return *expected_crypto_hash == actual_crypto_hash } fn crack_password(crypto_hash: String, length: u32) { println!("Processing number combinations sequentially"); let start_time = time::Instant::now(); let combinations: Vec<String> = get_combinations(length); for combination in combinations { if check_password(&crypto_hash.clone(), combination.clone()) { println!("PASSWORD CRACKED:{}", combination); break; } } println!("PROCESS TIME: {:?}", start_time.elapsed()); }
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.32s
Running `target/debug/parallel`
{5000: 10000, 0: 4999}
5000:10000
0:4999
PASSWORD CRACKED:5231
これは中々素晴らしいね^^