- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
<?php
function word_by_index($index, $dicts) {
$sizes = array_map(function($val){return count($val);}, $dicts); // получаем размеры каждого словаря
$result = '';
foreach($sizes as $key=>$size) {
$result .= $dicts[$key][$index % $size]; // сцепляем слово из частей
$index = floor($index / $size);
}
return $result;
}
function R($hash, $dicts, $total) {
$index = gmp_intval(gmp_mod(gmp_init($hash, 16), $total));
return word_by_index($index, $dicts);
}
function make_chain($start, $length, $dicts, $total) {
$chain['start'] = $start;
for($i = 0; $i < $length; ++$i) {
$hash = md5($start); // <-- сюда вставьте нужную хэш-функцию
// echo ">>> $hash : $start\n"; // диагностическое сообщение
$start = R($hash, $dicts, $total);
}
$chain['end'] = $hash;
echo "Chain from ${chain['start']} to ${chain['end']} is ready.\n"; // диагностическое сообщение
return $chain;
}
function make_chains($count, $length, $dicts) {
$sizes = array_map(function($val){return count($val);}, $dicts); // получаем размеры каждого словаря
$total = array_reduce($sizes, function($carry,$item){return $carry*$item;}, 1); // произведение размеров словарей
$chains = [];
mt_srand();
for($i = 0; $i < $count; ++$i) {
$word = word_by_index(mt_rand(0, $total - 1), $dicts); // начинаем цепочку с псевдослучайного слова
$chain = make_chain($word, $length, $dicts, $total);
$hash = $chain['end']; // используем конец найденной цепочки как индекс для быстрого поиска
if(!isset($chains[$hash])) $chains[$hash] = []; // если такого хэша не было в корзине, инициализируем её
if(!in_array($chain['start'], $chains[$hash])) { // проверяем на дубли
$chains[$hash][] = $chain['start']; // добавляем начало цепочки в корзину
}
}
return $chains;
}
function find_hash_in_basket($needle, $haystack_start, $haystack_end, $dicts, $total) {
echo "Роемся в цепочке от $haystack_start до $haystack_end.\n"; // диагностическое сообщение
$current_word = $haystack_start;
do {
$current_hash = md5($current_word); // <-- сюда вставьте нужную хэш-функцию
if($current_hash === $needle) {
return $current_word; // нашли слово, хэш от которого равен заданному
}
$current_word = R($current_hash, $dicts, $total); // роем в глубину
} while($current_hash !== $haystack_end);
return false; // не нашли
}
function search_hash($hash, $dicts, $chains, $length) {
$sizes = array_map(function($val){return count($val);}, $dicts); // получаем размеры каждого словаря
$total = array_reduce($sizes, function($carry,$item){return $carry*$item;}, 1); // произведение размеров словарей
$current_hash = $hash;
for($i = 0; $i < $length; ++$i) {
if(isset($chains[$current_hash])) { // нашли хэш в одной из корзин
echo "Лезем в корзину $current_hash.\n"; // диагностическое сообщение
foreach($chains[$current_hash] as $start) { // роемся в корзине
$result = find_hash_in_basket($hash, $start, $current_hash, $dicts, $total); // пытаемся найти в каждой из цепочек корзины
if($result) {
return $result; // конец поиска
}
}
}
$next_word = R($current_hash, $dicts, $total); // копаем в глубину
$current_hash = md5($next_word);
}
return false; // не нашли
}
///////////////////// ПРИМЕР //////////////////////////////////
$dicts= array(
array('свино', 'овце', 'тигро', 'косатко', 'зубро', 'волко', 'кото'),
array('собака', 'бык', 'лев', 'дельфин', 'бизон')
);
$chains = make_chains(15, 15, $dicts);
echo "Радужные таблицы готовы.\n";
var_dump($chains);
$hash = '360629d3cf05cee0240a23e1251c58a0';
echo "Пытаемся обратить $hash.\n";
$word = search_hash($hash, $dicts, $chains, 15);
echo "$hash is reversed to $word.\n";
По просьбам трудящихся.
Выхлоп на Ideone:
http://ideone.com/otdCDg