Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- extern crate crypto;
- extern crate num_cpus;
- use crypto::md5::Md5;
- use crypto::digest::Digest;
- use std::fmt::Write;
- use std::io;
- use std::thread;
- use std::sync::mpsc::channel;
- use std::u64;
- #[derive(Clone, Copy, Debug)]
- enum ThMsg {
- Digit(usize, char, u64),
- Part1Digit(char, u64),
- GroupSync,
- }
- use ThMsg::{Digit, Part1Digit, GroupSync};
- #[derive(Clone, Copy, Debug)]
- enum MainMsg {
- Ack,
- Die,
- }
- use MainMsg::{Ack, Die};
- #[inline]
- fn to_hex(n: u8) -> char {
- match n {
- 0...9 => (('0' as u8) + n) as char,
- 10...15 => (('a' as u8) + n - 10) as char,
- _ => '#',
- }
- }
- fn main() {
- let mut sh = Md5::new();
- sh.input_str("ojvtpuvg");
- let thcnt = num_cpus::get() as u64;
- println!("Starting {} threads", thcnt);
- let (thtx, mainrx) = channel();
- let mut maintxs = vec![];
- let mut threads = vec![];
- const PASSWORD_LEN: usize = 8;
- // create threads
- for i in 0..thcnt {
- let thtx = thtx.clone();
- let (maintx, thrx) = channel();
- maintxs.push(maintx);
- let thread = thread::spawn(move||{
- let mut idx = i;
- let mut buf = String::with_capacity(10);
- let mut syncpoint = 1_000_000;
- let syncstep = 1_000_000;
- let mut res = [0u8; 16];
- loop {
- let mut sh1 = sh.clone();
- write!(&mut buf, "{}", idx).unwrap();
- sh1.input_str(&buf);
- buf.clear();
- sh1.result(&mut res);
- if res[0] == 0 && res[1] == 0 && res[2]>>4 == 0 {
- thtx.send(Part1Digit(to_hex(res[2] & 0xf), idx)).unwrap();
- let i = (res[2]&0xf) as usize;
- thtx.send(Digit(i, to_hex(res[3] >> 4), idx)).unwrap();
- };
- idx += thcnt;
- if idx >= syncpoint {
- thtx.send(GroupSync).unwrap();
- // wait other threads
- match thrx.recv().unwrap() {
- Ack => (),
- Die => return,
- }
- syncpoint += syncstep;
- }
- }
- });
- threads.push(thread);
- }
- // collect thread data
- let mut code1 = vec![];
- let mut code2 = vec![(0xffff_ffff_ffff_ffffu64, '_'); PASSWORD_LEN];
- let mut synccnt = 0;
- loop {
- match mainrx.recv().unwrap() {
- GroupSync => {
- synccnt += 1;
- if synccnt == thcnt {
- // all threads reached GroupSync state
- // check for completion
- if code2.iter().all(|&(_, ch)| ch != '_') && code1.len() == PASSWORD_LEN {
- print!("Password1: ");
- for &(_, ch) in &code1 {
- print!("{}", ch);
- }
- println!("");
- print!("Password2: ");
- for &(_, ch) in &code2 {
- print!("{}", ch);
- }
- println!("");
- // done
- for tx in &maintxs {
- tx.send(Die).unwrap();
- };
- for thread in threads.drain(..) {
- thread.join().unwrap();
- }
- break;
- }
- synccnt = 0;
- // allow threads to continue
- for tx in &maintxs {
- tx.send(Ack).unwrap();
- };
- };
- },
- Digit(i, ch, idx) => {
- if i < PASSWORD_LEN && code2[i].0 > idx {
- code2[i] = (idx, ch);
- }
- print!("Decoding: ");
- for &(_, c) in &code2 {
- print!("{}", if c == '_' {ch} else {c});
- }
- print!("\r");
- io::Write::flush(&mut io::stdout()).unwrap();
- },
- Part1Digit(ch, idx) => {
- code1.push((idx, ch));
- code1.sort();
- code1.truncate(PASSWORD_LEN);
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement