fork download
  1. <?php
  2.  
  3. // debug
  4. set_error_handler(function ($errno, $errstr, $errfile, $errline ) {
  5. throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
  6. });
  7.  
  8. $charset = "abcdefghijklmnopqrstuvwxyz0123456789";
  9. $alphabet = PassCracker::createAlphabet($charset);
  10. $hash = "e7806b130b429fc9b5890608a2c60675";
  11.  
  12. $cracker = new PassCracker(4, $alphabet, false);
  13. $answer = $cracker->crack($hash);
  14. echo $answer !== null ?
  15. "Answer is $answer\n" :
  16. "This time we're out of luck. Try googling: http://google.com/?q=$hash\n";
  17.  
  18. class PassCracker
  19. {
  20. private $length;
  21. private $alphabet;
  22.  
  23. private $passwordIndexes;
  24. private $passwordLetters;
  25.  
  26. public function __construct($length, array $alphabet)
  27. {
  28. $this->length = $length;
  29. $this->alphabet = $alphabet;
  30. }
  31.  
  32. public static function createAlphabet($string)
  33. {
  34. return preg_split("//u", $string, null, PREG_SPLIT_NO_EMPTY);
  35. }
  36.  
  37. private function initCode()
  38. {
  39. $this->passwordIndexes = array_fill(0, $this->length, 0);
  40. $this->generatePassword();
  41. }
  42.  
  43. private function generatePassword()
  44. {
  45. $this->passwordLetters = array_map(function ($index) {
  46. return $this->alphabet[$index];
  47. }, $this->passwordIndexes);
  48. }
  49.  
  50. public function crack($hash)
  51. {
  52. $this->initCode();
  53. $hash = mb_strtolower(trim($hash)); // everything might happen
  54.  
  55. do {
  56.  
  57. $password = implode('', $this->passwordLetters);
  58. if (md5($password) == $hash) {
  59. return $password;
  60. }
  61.  
  62. if (!$this->generateNextCode()) {
  63. return null;
  64. };
  65.  
  66. } while (true);
  67.  
  68. }
  69.  
  70. private function generateNextCode() {
  71. $max = count($this->alphabet);
  72. for ($pos = $this->length - 1; $pos >= 0; $pos--) {
  73.  
  74. $newIndex = $this->passwordIndexes[$pos] = ($this->passwordIndexes[$pos] + 1) % $max;
  75. $this->passwordLetters[$pos] = $this->alphabet[$newIndex];
  76.  
  77. if ($newIndex > 0) {
  78. return true;
  79. }
  80. }
  81.  
  82. // No more tries
  83. return false;
  84. }
  85. }
  86.  
Success #stdin #stdout 2.04s 20520KB
stdin
Standard input is empty
stdout
Answer is omsk