Авторские статьи Декодирование капчи

Discussion in 'Статьи' started by 4nob1oz, 27 Feb 2008.

  1. 4nob1oz

    4nob1oz Elder - Старейшина

    Joined:
    9 Jul 2007
    Messages:
    30
    Likes Received:
    22
    Reputations:
    0
    Рыскав по инету я заменил, что опять какой то барыга продаёт кучу софта и в ней был хрумер 4. Я почитал описалово, прифигел и опять задумался над тем как же декодят эти капчи. Как то раз я уже пытался задекодить самую простую но ничего не вышло и я забил на это дело. В этот раз я наконец то написал скрипт который декодит одну из самых простейцих капч чему очень рад(ура я не такой тупой =)). В капче присутствует эффект шума и ничего более.

    Вот пример капчи:
    [​IMG]

    Алгоритм очень простой:
    -Переводим капчу в монохромное(чёрно-белое) изображение.
    -Ищем первый чёрный пиксел и после нахождения ставим флаг что это начало первый цифры
    -Сверяем каждую колонку пикселов идя вправо и суммируя чёрные до тех пор пока не дойдём до колонки где наша сумма не станет равной нулю.
    -Если стала равна нулю то значит один символ мы идентифицировали.
    -Обнуляем флаги.
    -Сравниваем сомвол с шаблонами.
    -Записываем в переменную для вывода задекоденной капчи.

    Итак обо всём попорядку.

    Переводим капчу в монохромное(чёрно-белое) изображение.
    ---------------------------------------------------------------------------

    Унас есть капча(пример выше). В чём её слабость. Ну первое что бросается в глаза это то, что все символы написаны белым. Так за это и нужно зацепиться. Алгоритм перевода в монохромное изображение будет таков, что все пикселы кроме белого мы переводим в белый, а белые пикселы в чёрный.

    Code:
    //Цикл перевода капчи в монохромное изображение
    for($i=0;$i<$width;$i++)
    {
    	for($j=0;$j<$height;$j++)
    	{
      // Получаем RGB пикселя по координате
      $color=imageColorAt($im,$i,$j);
      // Разбиваем RGB на Red,Green,Blue и записываем каждую составляющую в свою переменную
      list($r,$g,$b)=array_values(imageColorsForIndex($im,$color));
      //Сравнение белого ли цвета пиксель
      if($r==255 && $g=255 && $b==255)
      {
      	imagesetpixel($im,$i,$j,$black); // Установка пикселя в чёрный
      } else {
      	imagesetpixel($im,$i,$j,$white); // Установка пикселя в белый
      }
    	}
    }
    После этого капча станет такого вида.

    [​IMG]

    Далее нам нужно отсекать по каждому символу в капче. Разберём код

    Code:
    for($i=0;$i<$width;$i++)
    {
    	for($j=0;$j<$height;$j++)
    	{
      // Получаем RGB пикселя по координате
      $color=imageColorAt($im,$i,$j);
      // Разбиваем RGB на Red,Green,Blue и записываем каждую составляющую в свою переменную
      list($r,$g,$b)=array_values(imageColorsForIndex($im,$color));
      // Сравнение на чёрный пиксел
      if($r==0 && $g==0 && $b==0 && $left==0)
      {
          $left=1;
      	$black_pix++;
      }
            // Сравнение на чёрный пиксел и левую границу символа
      else if($r==0 && $g==0 && $b==0 && $left==1)
      {
      	$black_pix++;
      }
            // То же самое только ещё добавлна проверка на кол-во чёрных пикселов
      else if($r==0 && $g==0 && $b==0 && $left==1 && $black_pix==0)
      {
      	$left=0;
      	$black_pix=0;
      }
    	}
    
    Уже в монохромной капче мы ищем первый чёрный пиксел. Если это первый чёрный пиксе и флаг левой границы не установлен, то мы утсанавливаем этот флаг и увеличиваем переменную $black_pix которая отвечает за кол-во символов в данном столбце пикселов. Далее если флаг границы установлен, то мы просто увеличиваем переменную $black_pix, а вот если флаг границы утсановлен и переменная $black_pix равна нулю то значит мы достигли гонца первого символа и можем начать сравнеие по шаблонам предварительно обнулив переменную $black_pix и флаг $left.Каждый раз после подсчёта чёрных пикселов мы добавляли в переменную $char значение переменной $black_pix. Как это сделано можно посмотреть в коде декодера, здесь я этот момент затрагивать не стану.

    Идём дальше по коду.

    Сравниваем сомвол с шаблонами.
    -----------------------------------------

    Перед тем как делать сравнение я подготовил шаблоны для всех цифр которы есть в капче.

    Code:
    //Цикл сравнения цифры из капчи с каждой цифрой по шаблонам
        for($x=0;$x<count($templates);$x++)
        {
        	for($y=0;$y<count($templates[$x]);$y++)
        	{
          //Если равно кол-во чёрных пикселов то увеличиваем переменную OK
          if($char[$y]==$templates[$x][$y])
          {
          	//Увеличили совпадения
          	$ok++;
          	//Если кол-во совпадений больше либо равно 8 то нашли цифру
          	if($ok>=8)
          	{
            $out .= $x;
            break;
          	}
          }
        	}
        	//Обнуляем переменную совпадений
        	$ok=0;
        }
        //Обнуляем переменную символа
        $char='';
    }
    После того как мы отсекли первый символ мы можем начать сравнение. Как я уже говорил выше в переменной $char содержится количество символов в каждом стобце пикселов для данной отсечённой цифоы из капчи. Там будет чтото вроде 23433343. Это значит, что в ширина символа всего 8 пикселов и в первом столбце чёрных пиксела 2, во втором 3 ну итд.
    Исключение составляет только цифра 4, ширина то у неё тоже 8 пикселов, но кол-во чёрных пикселов в некоторых столбцах равно 10, а вот сравнение идёт побайтово и шаблон для цифры 4 был сделано из 10 символов. Ну и теперь можно сравнивать побайтово переменную $char с каждым шаблоном и если например первое байт из шаблона совпадает с первым байтом из переменной $char, то мы увеличиваем переменную $ok, ну а если кол-во совпадений становится 8 и больше то мы просто прерывааем цикли так как нашли цифру. В переменную $out записываем переменную $x так как символы расположены по порядку в массиве $templates то $x будет соответствовать искомой цифре.

    Капчи были взяты с сайта http://dign.narod.ru/, но там нет готового решения, я решил написать и от что получилось :)

    Архив с капчами
    --------------------

    Link: http://webfile.ru/1769225

    Полный код
    ---------------

    Captcha(very_easy).php
    Code:
    <?
    $image = "01.png"; // Сама капча
    
    $black_pix=0; // Кол-во чёрных пикселей по высоте
    $left=0;  // Левая граница каждой цифры
    $ok=0;    // Кол-во совпадений
    
    //Шаблоны цифр
    $zero  = array(4,6,4,4,4,4,6,4);
    $one   = array(2,3,1,0,1,0,1,1);
    $two   = array(2,4,5,4,4,5,5,3);
    $three = array(2,4,2,3,3,7,7,3);
    $four  = array(2,3,3,3,3,1,0,1,0,1);
    $five  = array(6,7,4,3,3,5,6,3);
    $six   = array(6,8,5,3,3,6,6,2);
    $seven = array(3,4,3,3,3,3,4,3);
    $eigth = array(3,7,7,3,3,7,7,3);
    $nine  = array(2,6,6,3,3,5,8,6);
    
    //Большой массив который содержит все шаблоны
    $templates = array($zero,$one,$two,$three,$four,$five,$six,$seven,$eigth,$nine);
    
    //Ширина и высота капчи
    list($width,$height) = getimagesize($image);
    
    //Получаем хендл капчи
    $im = imagecreatefrompng($image);
    
    //определяем чёрный и белые цвета
    $white = imagecolorallocate($im,255,255,255);
    $black = imagecolorallocate($im, 0, 0, 0);
    
    //Цикл перевода капчи в монохромное изображение
    for($i=0;$i<$width;$i++)
    {
    	for($j=0;$j<$height;$j++)
    	{
      // Получаем RGB пикселя по координате
      $color=imageColorAt($im,$i,$j);
      // Разбиваем RGB на Red,Green,Blue и записываем каждую составляющую в свою переменную
      list($r,$g,$b)=array_values(imageColorsForIndex($im,$color));
      //Сравнение белого ли цвета пиксель
      if($r==255 && $g=255 && $b==255)
      {
      	imagesetpixel($im,$i,$j,$black); // Установка пикселя в чёрный
      } else {
      	imagesetpixel($im,$i,$j,$white); // Установка пикселя в белый
      }
    	}
    }
    
    // Цикл декодирования монохромной капчи
    for($i=0;$i<$width;$i++)
    {
    	for($j=0;$j<$height;$j++)
    	{
      // Получаем RGB пикселя по координате
      $color=imageColorAt($im,$i,$j);
      // Разбиваем RGB на Red,Green,Blue и записываем каждую составляющую в свою переменную
      list($r,$g,$b)=array_values(imageColorsForIndex($im,$color));
      // Сравнение на чёрный пиксел
      if($r==0 && $g==0 && $b==0 && $left==0)
      {
          $left=1;
      	$black_pix++;
      }
            // Сравнение на чёрный пиксел и левую границу символа
      else if($r==0 && $g==0 && $b==0 && $left==1)
      {
      	$black_pix++;
      }
            // То же самое только ещё добавлна проверка на кол-во чёрных пикселов
      else if($r==0 && $g==0 && $b==0 && $left==1 && $black_pix==0)
      {
      	$left=0;
      	$black_pix=0;
      }
    	}
    	//Проверка равено ли кол-во чёрных пикселов в столбце 0
        if($black_pix!=0)
        {
        	$char .= $black_pix;
        } else {
        	//Цикл сравнения цифры с каждой цифрой по шаблонам
        	for($x=0;$x<count($templates);$x++)
        	{
          for($y=0;$y<count($templates[$x]);$y++)
          {
          	//Если равно кол-во чёрных пикселов то увеличиваем переменную OK
          	if($char[$y]==$templates[$x][$y])
          	{
            //Увеличили совпадения
            $ok++;
            //Если кол-во совпадений больше либо равно 8 то нашли цифру
            if($ok>=8)
            {
            	$out .= $x;
            	break;
            }
          	}
          }
          //Обнуляем переменную совпадений
          $ok=0;
        	}
        	//Обнуляем переменную символа
        	$char='';
    	}
    	//Обнуляем переменную кол-ва чёрных пикселов
    	$black_pix=0;
    }
    
    //Вывод капчи и прочей информации
    print("<font color=grey>--------------------------<br>");
    print("Sample captcha decode:<br>");
    print("--------------------------</font><br>");
    print("<img src=".$image."> <b><---></b> <font color=red><b>".$out."</b></font>");
    print("<br>(c)Coded by <b>perdimonokl aka 4nob1oz</b> just for fun");
    
    //Закрываем хендл капчи
    imagedestroy($im);
    ?>
    Если чтото для вас стало сложно или непонятно, если есть какие то предложение или замечания, пишите в ПМ, пишите здесь, пишите в асю или жабер(если знаете конечно).

    Вот и всё...

    ©Coded by perdimonokl aka 4nob1oz just for fun
     
    13 people like this.
  2. diehard

    diehard Elder - Старейшина

    Joined:
    30 Sep 2007
    Messages:
    442
    Likes Received:
    266
    Reputations:
    15
    простая капча - простой алгоритм. Насколько я помню для распознавания письма на изображениях используются обучаемые алгоритмы на основе нейронных сетей
     
    1 person likes this.
  3. banned

    banned Banned

    Joined:
    20 Nov 2006
    Messages:
    3,324
    Likes Received:
    1,193
    Reputations:
    252
    Была статья от Nomer1, там код реализован короче и лучше..

    + только за то что способ твой(если он твой)
     
    1 person likes this.
  4. Conquerstador

    Conquerstador Banned

    Joined:
    7 Jul 2007
    Messages:
    124
    Likes Received:
    39
    Reputations:
    -6
    это все конечно хорошо и + конечно но вот бы скрипт чтобы с капчи автоматом прописывалась вот это было бы реал, хотя фантазия но все равно )))
     
  5. KEZ

    KEZ Ненасытный школьник

    Joined:
    18 May 2005
    Messages:
    1,604
    Likes Received:
    754
    Reputations:
    397
    еголд попробуйте распознать
     
  6. 4nob1oz

    4nob1oz Elder - Старейшина

    Joined:
    9 Jul 2007
    Messages:
    30
    Likes Received:
    22
    Reputations:
    0
    На еголде :) Там жесть вообще :)
     
  7. +toxa+

    +toxa+ Smack! SMACK!!!

    Joined:
    16 Jan 2005
    Messages:
    1,674
    Likes Received:
    1,029
    Reputations:
    1,228
    4nob1oz
    на mail.ru посмотри новую)
     
    _________________________
    1 person likes this.
  8. Хозяин

    Хозяин Elder - Старейшина

    Joined:
    15 Mar 2006
    Messages:
    435
    Likes Received:
    404
    Reputations:
    110
    +toxa+, рвется она уже )))
     
  9. ProTeuS

    ProTeuS --

    Joined:
    26 Nov 2004
    Messages:
    1,239
    Likes Received:
    542
    Reputations:
    445
    статья боян, сорцов аналоги4ных тулх давно пруд пруди, и на основе нейросетей. инетерсно было бы 4итать разве4то реализацию алго выделения изображений, переворота и горизонального\вертикального проэцирования
     
  10. ElteRUS

    ElteRUS Elder - Старейшина

    Joined:
    11 Oct 2007
    Messages:
    367
    Likes Received:
    460
    Reputations:
    93
    Про распознавание примитивных капчей уже писали ТУТ и ТУТ . Да и вобще нету особых проблем в том, что бы распознать такие капчи. Лучше б написали что-то об методах фильтрации шумов, проведении сегментации и распознавании искаженных символов (блин, забыл термин, такой прикольный... которым обозначают искажение символов )))
     
  11. 4nob1oz

    4nob1oz Elder - Старейшина

    Joined:
    9 Jul 2007
    Messages:
    30
    Likes Received:
    22
    Reputations:
    0
    Пипец заглянул на mail.ru, вот это капча так капча :) А про распознование искажённых символов вред ли тебе ктото расскажет и тем более покажет, я видел только одну статью и там просто рассказывалось про алгоритм.

    А тем кто тут пишет что типа боян и что кодов и алгов, а конкретнее я говорю про тебя ProTeuS, что от вас я вообще не видел ни одной статьи, ни одного релиза, ни одного сплоита даже ДоС, такие как ты позорят расскую сцену и гнут свои пальцы но сами из себя ничего не представляют. Ты 0 ты никто тебя никто не знает ты пустое место и мне твоё мнение не важно, я послушаю прислушаюсь к мнению Great, Сталина, Кеза, Электа, Краша, +Тохи+ и ещё многих других сильных в тех плане парней но не твоё...
     
    2 people like this.
  12. NOmeR1

    NOmeR1 Everybody lies

    Joined:
    2 Jun 2006
    Messages:
    1,068
    Likes Received:
    783
    Reputations:
    213
    Мне понравилась статья. Мой способ менее автоматизирован, да и продуман не сильно.
     
  13. _Great_

    _Great_ Elder - Старейшина

    Joined:
    27 Dec 2005
    Messages:
    2,032
    Likes Received:
    1,119
    Reputations:
    1,139
    Прислушайся: закрой рот. И не открывай больше

    ЗЫ. А статья, действительно, боян
     
    #13 _Great_, 28 Feb 2008
    Last edited: 28 Feb 2008
    3 people like this.
  14. ElteRUS

    ElteRUS Elder - Старейшина

    Joined:
    11 Oct 2007
    Messages:
    367
    Likes Received:
    460
    Reputations:
    93
    Ну вот, если ты видел алгоритм, то почему б было не написать по нему скрипт\статью ? Многие тебе были б благодарны - это действительно интересно и актуально и не боян.

    Если не жалко, дай ссылку на ту статью.
     
  15. 4nob1oz

    4nob1oz Elder - Старейшина

    Joined:
    9 Jul 2007
    Messages:
    30
    Likes Received:
    22
    Reputations:
    0
    Дак найти бы ещё её эту статью. Пороюсь может и найду, но написать точно не напишу там вообще нереально для моего понимания :)
     
    1 person likes this.
  16. fucker"ok

    fucker"ok Elder - Старейшина

    Joined:
    21 Nov 2004
    Messages:
    580
    Likes Received:
    279
    Reputations:
    91
    даешь нейросети!
     
  17. lsass.exe

    lsass.exe Elder - Старейшина

    Joined:
    5 Aug 2007
    Messages:
    156
    Likes Received:
    161
    Reputations:
    24
    http://dign.narod.ru/
    Имхо взято отсюда, тока переписано на пхп ;)
     
  18. orcismylife

    orcismylife Elder - Старейшина

    Joined:
    1 Oct 2007
    Messages:
    22
    Likes Received:
    6
    Reputations:
    0
    Вообще-то у него в статье ссылка на этот сайт и есть.
    А так - понравилось.

    //Автор, не выёбывайся только с вашей помойкой-tgbr и любимых ваших высказываниях, как кто-то позорит русскую хак сцену. Сам же в начале повествуешь, что твой алгоритм для нубских капчей. Да и вообще, сомневаюсь, что итальянский хекер будет читать этот топик в онлайн переводчике и своим тиммейтам рассказывать, какой в России народ.

    Что-то я разошёлся.
     
  19. Constantine

    Constantine Elder - Старейшина

    Joined:
    24 Nov 2006
    Messages:
    798
    Likes Received:
    710
    Reputations:
    301
    боян, тема сисек не раскрыта. автор хам
     
  20. vadim399

    vadim399 Banned

    Joined:
    27 May 2007
    Messages:
    325
    Likes Received:
    180
    Reputations:
    -3
    Щас на рапиде капча с кошками и собаками идет О_о