Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #![feature(static_in_const)]
- extern crate crypto;
- extern crate iterslide;
- extern crate rayon;
- use crypto::digest::Digest;
- use crypto::md5::Md5;
- use iterslide::SlideIterator;
- use rayon::prelude::*;
- use std::collections::VecDeque;
- const SALT: &[u8] = b"ahsbgdzn";
- fn to_nibble(x: u8) -> u8 {
- if x < 10 { b'0' + x } else { b'a' + x - 10 }
- }
- fn from_nibble(c: u8) -> u8 {
- if c <= b'9' { c - b'0' } else { c - b'a' + 10 }
- }
- fn expand_to_hex(v: &mut [u8]) {
- for i in 0..16 {
- let x = v[16 + i];
- v[2 * i] = to_nibble(x >> 4);
- v[2 * i + 1] = to_nibble(x & 0xf);
- }
- }
- fn hash(salt: &[u8], n: usize, loops: usize) -> [u8;32] {
- let mut buffer = [0; 32];
- let mut md5 = Md5::new();
- md5.input(salt);
- md5.input_str(&n.to_string());
- for _ in 0..loops {
- md5.result(&mut buffer[16..32]);
- expand_to_hex(&mut buffer);
- md5.reset();
- md5.input(&buffer);
- }
- let mut r = [0;32];
- r.clone_from_slice(md5.result_str().as_bytes());
- r
- }
- struct MD5Iter { salt: Vec<u8>, index: usize, loops: usize, pool: VecDeque<[u8;32]> }
- impl Iterator for MD5Iter {
- type Item = [u8;32];
- fn next(&mut self) -> Option<[u8;32]> {
- if self.pool.is_empty() {
- const BATCH_SIZE: usize = 1000;
- self.pool.reserve_exact(BATCH_SIZE);
- let mut replenish = Vec::with_capacity(BATCH_SIZE);
- (self.index .. self.index + BATCH_SIZE).into_par_iter().weight_max()
- .map(|n| hash(&self.salt, n, self.loops)).collect_into(&mut replenish);
- for e in replenish.into_iter() {
- self.pool.push_back(e);
- }
- self.index += BATCH_SIZE;
- }
- self.pool.pop_front()
- }
- }
- fn three_and_fives(s: [u8; 32]) -> (Option<u8>, u16) {
- let mut three = None;
- let mut fives = 0;
- for i in 0 .. s.len() - 3 {
- let c = s[i];
- if s[i+1] == c && s[i+2] == c {
- if three == None {
- three = Some(from_nibble(c));
- }
- if i < s.len() - 5 && s[i+3] == c && s[i+4] == c {
- fives |= 1 << from_nibble(c);
- if fives == 0xff {
- break;
- }
- }
- }
- }
- (three, fives)
- }
- fn p14(salt: &[u8], mut index: u32, loops: usize) -> usize {
- let md5s = MD5Iter { salt: salt.to_vec(), index: 0, loops: loops, pool: VecDeque::new() };
- for v in md5s.into_iter().enumerate().map(|(n, s)| {
- let (t, f) = three_and_fives(s);
- (t, f, n)
- }).slide(1001).filter(|v| {
- if let Some(t) = v[0].0 {
- v.into_iter().skip(1).any(move |&(_, f, _)| f & (1 << t) != 0)
- } else {
- false
- }
- }) { if index == 0 { return v[0].2; } else { index -= 1; } }
- 0
- }
- fn main() {
- println!("P1 = {}", p14(SALT, 63, 0));
- println!("P2 = {}", p14(SALT, 63, 2016));
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement