Advertisement
Guest User

Untitled

a guest
Dec 16th, 2016
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 2.98 KB | None | 0 0
  1. #![feature(static_in_const)]                        
  2.  
  3. extern crate crypto;
  4. extern crate iterslide;
  5. extern crate rayon;
  6.  
  7. use crypto::digest::Digest;
  8. use crypto::md5::Md5;
  9. use iterslide::SlideIterator;
  10. use rayon::prelude::*;
  11. use std::collections::VecDeque;
  12.  
  13. const SALT: &[u8] = b"ahsbgdzn";
  14.  
  15. fn to_nibble(x: u8) -> u8 {
  16.     if x < 10 { b'0' + x } else { b'a' + x - 10 }
  17. }
  18.  
  19. fn from_nibble(c: u8) -> u8 {
  20.     if c <= b'9' { c - b'0' } else { c - b'a' + 10 }
  21. }
  22.  
  23. fn expand_to_hex(v: &mut [u8]) {
  24.     for i in 0..16 {
  25.         let x = v[16 + i];
  26.         v[2 * i] = to_nibble(x >> 4);
  27.         v[2 * i + 1] = to_nibble(x & 0xf);
  28.     }
  29. }
  30.  
  31. fn hash(salt: &[u8], n: usize, loops: usize) -> [u8;32] {
  32.     let mut buffer = [0; 32];
  33.     let mut md5 = Md5::new();
  34.     md5.input(salt);
  35.     md5.input_str(&n.to_string());
  36.     for _ in 0..loops {
  37.         md5.result(&mut buffer[16..32]);
  38.         expand_to_hex(&mut buffer);
  39.         md5.reset();
  40.         md5.input(&buffer);
  41.     }
  42.     let mut r = [0;32];
  43.     r.clone_from_slice(md5.result_str().as_bytes());
  44.     r
  45. }
  46.  
  47. struct MD5Iter { salt: Vec<u8>, index: usize, loops: usize, pool: VecDeque<[u8;32]> }
  48.  
  49. impl Iterator for MD5Iter {
  50.     type Item = [u8;32];
  51.  
  52.     fn next(&mut self) -> Option<[u8;32]> {
  53.         if self.pool.is_empty() {
  54.             const BATCH_SIZE: usize = 1000;
  55.             self.pool.reserve_exact(BATCH_SIZE);
  56.             let mut replenish = Vec::with_capacity(BATCH_SIZE);
  57.             (self.index .. self.index + BATCH_SIZE).into_par_iter().weight_max()
  58.                 .map(|n| hash(&self.salt, n, self.loops)).collect_into(&mut replenish);
  59.             for e in replenish.into_iter() {
  60.                 self.pool.push_back(e);
  61.             }
  62.             self.index += BATCH_SIZE;
  63.         }
  64.         self.pool.pop_front()
  65.     }
  66. }
  67.  
  68. fn three_and_fives(s: [u8; 32]) -> (Option<u8>, u16) {
  69.     let mut three = None;
  70.     let mut fives = 0;
  71.     for i in 0 .. s.len() - 3 {
  72.         let c = s[i];
  73.         if s[i+1] == c && s[i+2] == c {
  74.             if three == None {
  75.                 three = Some(from_nibble(c));
  76.             }
  77.             if i < s.len() - 5 && s[i+3] == c && s[i+4] == c {
  78.                 fives |= 1 << from_nibble(c);
  79.                 if fives == 0xff {
  80.                     break;
  81.                 }
  82.             }
  83.         }
  84.     }
  85.     (three, fives)
  86. }
  87.  
  88. fn p14(salt: &[u8], mut index: u32, loops: usize) -> usize {
  89.     let md5s = MD5Iter { salt: salt.to_vec(), index: 0, loops: loops, pool: VecDeque::new() };
  90.     for v in md5s.into_iter().enumerate().map(|(n, s)| {
  91.         let (t, f) = three_and_fives(s);
  92.         (t, f, n)
  93.     }).slide(1001).filter(|v| {
  94.         if let Some(t) = v[0].0 {
  95.             v.into_iter().skip(1).any(move |&(_, f, _)| f & (1 << t) != 0)
  96.         } else {
  97.             false
  98.         }
  99.     }) { if index == 0 { return v[0].2; } else { index -= 1; } }
  100.     0
  101. }
  102.  
  103. fn main() {
  104.     println!("P1 = {}", p14(SALT, 63, 0));
  105.     println!("P2 = {}", p14(SALT, 63, 2016));
  106. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement