Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Ответ 012 на задачу N 4
 
 автор: SoftTime   (07.02.2006 в 19:34)   письмо автору
 
 

Ответ 012 на задачу N 4.
С условиями задачи можно ознакомится по ссылке.
Наверное, это наглость с моей стороны - отправлять второе решение.
Но уж больно кривым смотрится первое по сравнению с ним.
Этот вариант находит все пароли сразу быстрее, чем первый находил один.


<html>
 <body>
  <form>
  Char set: <input name=set value=abcdefghijklmnopqrstuvwxyz size=30 />
<br>Max chars: <input name=depth value=4 size=2 />
<br>Md5 hashes list:
<textarea cols=35 rows=5 name=hashlist /
>ee11cbb19052e40b07aac0ca060c23ee
dd97813dd40be87559aaefed642c3fbb
8dbc672497bdc46f88e864bb1121232c
3e10f8c809242d3a0f94c18e7addb866
7fa3b767c460b54a2be4d49030b349c7
a6105c0a611b41b08f1209506350279e
865c0c0b4ab0e063e5caa3387c1a8741
d41d8cd98f00b204e9800998ecf8427e
</textarea>
<br><input type=submit />  </form>

<?php
   
//----------------------------------------------------------------------
   // поиск паролей для известных md5-хешей
   // метод: прямой перебор строк символов заданного алфавита ограниченной длины
   // строки строятся рекурсивно. Для увеличения производительности некоторые
   // статические параметры определены глобально
   //----------------------------------------------------------------------
   
global $hashlist$tries$set$setlen$start_time;

   
//----------------------------------------------------------------------
   // result($hash, $res) заносит в отчет успешно найденный пароль $res,
   // выносит хеш $hash из ключей массива $hashlist
   // Возвращается число еще не найденных ключей
   // глобальные параметры:
   //      $hashlist  - массив искомый хешей (в ключах)
   //      $tries - счетчик попыток
   //      $start_time - время начала перебора (для статистики)

   
function result($hash$res)
   {
         global 
$hashlist$tries;
         global 
$start_time;

         unset(
$hashlist[$hash]);
         
$elapsed sprintf('%.3f'mytime() - $start_time);
   echo(
"<tr><td>$hash</td><td>$res</td><td>$tries</td><td>$elapsed</td></tr>
"
);
         return 
count($hashlist);
   }

   
//----------------------------------------------------------------------
   // trypass рекурсивно пытается найти строку состоящую из $prefix
   // и $width символов из набора $set,  md5 которой присутствует среди ключей
   // массива $hashlist. Успех регистрируется вызовом функции result.
   //
   // Возвращается 0, если все пароли нашлись, и не 0 в противном случае.
   // корневой вызов:
   //   trypass("", длина пароля)
   // глобальные параметры:
   //      $hash  - искомый хеш
   //      $tries - счетчик попыток
   //      $set   - строка с символами алфавита
   //      $setlen- её длина (опять же ради скорости)
   //----------------------------------------------------------------------
   
function trypass($prefix$width)
   {
        global 
$hashlist$tries$set$setlen;

        
// самый глубокий (листовой) слой рекурсии расписан руками,
        // поскольку проверки на глубину все равно оказались нужны
        //(иначе не обеспечить обход множества паролей в ширину, а не в глубину.
        //В глубину же пароли искать смысл невелик, поскольку на практике
        //реальная его длина неизвестна, и искать надо от короткого к длинному.)
        
if(--$width <= 0)  // листовой слой
          
for($i 0$i $setlen$i++)
          {
              ++
$tries;    // еще одна попытка
              
$res $prefix.$set{$i};
              
$rm5 md5($res);
              if(isset(
$hashlist[$rm5]))
                  return 
result($rm5$res);
          }
        else 
// нелистовые слои
          
for($i 0$i $setlen$i++)
               if(
trypass($prefix.$set{$i}, $width) == 0)
                   return 
0// проверим и вернемся, если хеши кончились
        
return -1;   // на этом уровне не нашли
   
}

   function 
mytime() //обложка для вещественного time
   
{                 //(ибо get_as_float работает лишь с 5 версии PHP)
       
list($usec$sec) = explode(" "microtime());
       return ((float)
$usec + (float)$sec);
   }

   if(   isset(
$_REQUEST['hashlist'])
      && isset(
$_REQUEST['depth'])
      && isset(
$_REQUEST['set'])  )
   {
        
$set   $_REQUEST['set'];  // строка с алфавитом
        
$setlen strlen($set);     // и его размер

        
$hash  explode("
"
trim($_REQUEST['hashlist']));
        
$hashlist = array(); // переносим строки хешей в ключи массива $haslist
        
foreach($hash as $v$hashlist[trim($v)] = 0;
                            
// формируем заголовок отчета
   
echo("<table><tr><td>hash</td><td>res</td><td>tries</td><td>elapsed</td></tr>
"
);
        
$start_time mytime();  // засекаем время,
        
$tries 1;             // сбрасываем счетчик
                               // и отдельно проверяем случай пустого пароля
        
if(isset($hashlist['d41d8cd98f00b204e9800998ecf8427e'])) // === md5('')
             
result('d41d8cd98f00b204e9800998ecf8427e''');
                             
// далее ищем пароли длины от 1 до предельной
        
for($width 1$width <= $_REQUEST['depth']; ++$width)
             if(
trypass('',$width)==0// и если нашли все пароли
                 
break;                //      останавливаем поиск
        
$delta_time mytime() - $start_time;
        
$elapsed sprintf('%.3f'$delta_time); //считаем статистику
        
$pwd_per_sec $tries/$delta_time;
        
$speed sprintf('%.1f'$tries/$elapsed);
        echo(
"</table>
Total passwords checked: 
$tries<br>"
            
."Time elapsed: $elapsed s<br>Check speed:  $speed s<br>");

        if(
count($hashlist))     // если найдены не все
        
{                        // выводим оставшиеся хеши
           
echo( "Unable to detect plaintext {$_REQUEST['depth']} chars length "
                 
." with md5 hashes:<br>");
           foreach(
$hashlist as $k => $v)  echo( " '$k'<br>");
        }
   }
?>
 </body>
</html>


http://www.softtime.ru/info/task.php?id_article=74

   
 
 автор: cheops   (08.02.2006 в 23:59)   письмо автору
 
   для: SoftTime   (07.02.2006 в 19:34)
 

Немного громоздко, зато очень функционально и удобно, проверяется случай пустого пароля, нет вложенных циклов и обрабатываются все пароли в куче. Юзабилити и настройка скрипта - высший класс.

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования