Ну что ж вот ещё одна моя статья это уже вторая по счету. И так, речь пойдет о разгадывании капчи. Возьмем за основу мою первую статью. То есть капча будет та же. Действия которые мы будем производить: 1)Чистим капчу(Моя первая статья) . 2)Немного обрежем капчу(Немного переделаем код из первой статьи). 3)Переведем картинку в 0 и 1(где 0 – фон, а 1-составляющая цифры или буквы). 4)Грубо говоря вытаскиваем символы. 5)Чистим их от ненужного. 6)Находим в массиве схождения и выдаем уже расшифрованные символы. Вот в 6 шагов мы уложимся для того что бы написать код. Начнем с начала. Давайте вот эту капчу немного обрежем сразу Было Стало То есть немного изменив код из первой статьи мы достигли именно такого результата(много объяснять не буду, а сразу скину код) Code: <?php $img = @imagecreatefrompng($file); header ('Content-Type: image/png'); $img_o = imagecreatetruecolor(68, 15); imagecopy($img_o, $img, 0, 0, 5, 4, 68, 15); imagepng($img_o); $new_image = imagecreatetruecolor(68, 15); for($x=0;$x<69;$x++){ for($y=0;$y<16;$y++){ $rgb = imagecolorat($img_o,$x,$y); $r = 0; if(imagecolorat($img_o,$x-1,$y) == $rgb){ $r++; } if(imagecolorat($img_o,$x+1,$y) == $rgb){ $r++; } if(imagecolorat($img_o,$x,$y-1) == $rgb){ $r++; } if(imagecolorat($img_o,$x,$y+1) == $rgb){ $r++; } if($r == 0){ imagesetpixel($new_image,$x,$y,'15265527'); }else{ imagesetpixel($new_image,$x,$y,$rgb); } } } Imagepng($new_image); ?> В общем вот так размеры стали 68х15 Первые два шага мы выполнили теперь будем переводить в 0 и 1 Тут вообще нет ничего сложного Снова запускаем цикл for который будет читать с первого пикселя по последний(с учетом что размеры у нас уже другие картинка обрезана) Code: for($y=0;$y<15;$y++){ for($x=0;$x<68;$x++){ Вот так запустили цикл и смотрим пиксели если он равен фону(фон кстати не белый учтите это) то ставим 0, а если это другой цвет то 1 сделать это можно с помощью одной строчки кода Code: $num = (imagecolorat($new_image,$x,$y) == '15265527')? '0':'1'; Вот и все. Просто, да? Иначе это можно записать вот так Code: If(imagecolorat($new_image,$x,$y) == '15265527'){ $num .= ‘0’; }else{ $num .= ‘1’; } В результате у нас будет получаться вот такой вывод Можно увидеть 4 символа “916f” Так теперь грубо говоря вытаскиваем символы но для этого подсчитав сколько символов в одной строке уходит на сам символ(немного непонятно объяснил но вот на скрине ниже поймете) В общем просто воспользовавшись вот таким кодом(если честно то я сейчас горю желанием просто все бросить и дописать завтра, но увы нет) Code: if($x<8){ $num1[$y] .= $num; } if($x>19 and $x<28){ $num2[$y] .= $num; } if($x>39 and $x<48){ $num3[$y] .= $num; } if($x>59 and $x<68){ $num4[$y] .= $num; } Мы создаем массив с символами где $num1, $num2, $num3, $num4 это 4 символа и все они сейчас выглядят вот так, Это наша 9 так же выглядят другие массивы то есть один символ из 8 символов. Теперь снова займемся чисткой, уберем строки с 0 и приведем к вот такому виду Вот этой функцией Code: for($q=0;$q<count($num1);$q++){ if($num1[$q] != '00000000'){ $numi1[$nums1++] = $num1[$q]; } if($num2[$q] != '00000000'){ $numi2[$nums2++] = $num2[$q]; } if($num3[$q] != '00000000'){ $numi3[$nums3++] = $num3[$q]; } if($num4[$q] != '00000000'){ $numi4[$nums4++] = $num4[$q]; } } Ах, да забыл сказать для чего мы это делаем если ещё сгенерировать пару капч на том сайте от куда я взял эту то можно видеть что они постоянно меняют положение то выше то ниже, но не сдвигаются в лево в право.(Да и если ты продвинутый php программист и уже считаем меня говно кодером, то это твое право, просто я делаю для себя и меня такой метод устраивает) Ладно, далее объединяем массивы в строку Code: $string1 = ''; $string2 = ''; $string3 = ''; $string4 = ''; for($q=0;$q<count($numi1);$q++){ $string1 .= $numi1[$q]; }; for($q=0;$q<count($numi2);$q++){ $string2 .= $numi2[$q]; }; for($q=0;$q<count($numi3);$q++){ $string3 .= $numi3[$q]; }; for($q=0;$q<count($numi4);$q++){ $string4 .= $numi4[$q]; }; И сравниваем с заранее подготовленным шаблоном ответов Code: $array = Array('00011000001111000110011011000011110000111100001111000011011001100011110000011000'=>'0', '00011000001110000111100000011000000110000001100000011000000110000001100001111110'=>'1', '00111100011001101100001100000011000001100000110000011000001100000110000011111111'=>'2', '01111100110001100000001100000110000111000000011000000011000000111100011001111100'=>'3', '00000110000011100001111000110110011001101100011011111111000001100000011000000110'=>'4', '11111110110000001100000011011100111001100000001100000011110000110110011000111100'=>'5', '00111100011001101100001011000000110111001110011011000011110000110110011000111100'=>'6', '11111111000000110000001100000110000011000001100000110000011000001100000011000000'=>'7', '00111100011001101100001101100110001111000110011011000011110000110110011000111100'=>'8', '00111100011001101100001111000011011001110011101100000011010000110110011000111100'=>'9', '00111110011000110000001101111111110000111100011101111011'=>'a', '11000000110000001100000011011100111001101100001111000011110000111110011011011100'=>'b', '00111110011000111100000011000000110000000110001100111110'=>'c', '00000011000000110000001100111011011001111100001111000011110000110110011100111011'=>'d', '00111100011001101100001111111111110000000110001100111110'=>'e', '00011110001100110011001100110000001100001111110000110000001100000011000000110000'=>'f' ); Я не знаю почему эта капча которую я отгадываю постоянно генерирует цифры от “0” до “9” и буквы от “a” до “f” Да что бы не запутать возьмем один параметр из массива для примера Code: '00111110011000111100000011000000110000000110001100111110'=>'c', Если отсчитывать по 8 символов и жать enter то получится вот так Code: '00111110 01100011 11000000 11000000 11000000 01100011 00111110'=>'c', То вот с чем мы сравниваем, я сделал распознавание в виде функции Code: function captcha($file){ где $file эта файл капчи а в конце Code: return $array[$string1].$array[$string2].$array[$string3].$array[$string4]; } Конечный код выглядит вот так Code: <?php function captcha($file){ $img = @imagecreatefrompng($file); //header ('Content-Type: image/png'); $img_o = imagecreatetruecolor(68, 15); imagecopy($img_o, $img, 0, 0, 5, 4, 68, 15); $new_image = imagecreatetruecolor(68, 15); for($x=0;$x<69;$x++){ for($y=0;$y<16;$y++){ $rgb = imagecolorat($img_o,$x,$y); $r = 0; if(imagecolorat($img_o,$x-1,$y) == $rgb){ $r++; } if(imagecolorat($img_o,$x+1,$y) == $rgb){ $r++; } if(imagecolorat($img_o,$x,$y-1) == $rgb){ $r++; } if(imagecolorat($img_o,$x,$y+1) == $rgb){ $r++; } if($r == 0){ imagesetpixel($new_image,$x,$y,'15265527'); }else{ imagesetpixel($new_image,$x,$y,$rgb); } } } for($y=0;$y<15;$y++){ for($x=0;$x<68;$x++){ $num = (imagecolorat($new_image,$x,$y) == '15265527')? '0':'1'; if($x<8){ $num1[$y] .= $num; } if($x>19 and $x<28){ $num2[$y] .= $num; } if($x>39 and $x<48){ $num3[$y] .= $num; } if($x>59 and $x<68){ $num4[$y] .= $num; } } } $nums1 = 0; $nums2 = 0; $nums3 = 0; $nums4 = 0; for($q=0;$q<count($num1);$q++){ if($num1[$q] != '00000000'){ $numi1[$nums1++] = $num1[$q]; } if($num2[$q] != '00000000'){ $numi2[$nums2++] = $num2[$q]; } if($num3[$q] != '00000000'){ $numi3[$nums3++] = $num3[$q]; } if($num4[$q] != '00000000'){ $numi4[$nums4++] = $num4[$q]; } } $array = Array('00011000001111000110011011000011110000111100001111000011011001100011110000011000'=>'0', '00011000001110000111100000011000000110000001100000011000000110000001100001111110'=>'1', '00111100011001101100001100000011000001100000110000011000001100000110000011111111'=>'2', '01111100110001100000001100000110000111000000011000000011000000111100011001111100'=>'3', '00000110000011100001111000110110011001101100011011111111000001100000011000000110'=>'4', '11111110110000001100000011011100111001100000001100000011110000110110011000111100'=>'5', '00111100011001101100001011000000110111001110011011000011110000110110011000111100'=>'6', '11111111000000110000001100000110000011000001100000110000011000001100000011000000'=>'7', '00111100011001101100001101100110001111000110011011000011110000110110011000111100'=>'8', '00111100011001101100001111000011011001110011101100000011010000110110011000111100'=>'9', '00111110011000110000001101111111110000111100011101111011'=>'a', '11000000110000001100000011011100111001101100001111000011110000111110011011011100'=>'b', '00111110011000111100000011000000110000000110001100111110'=>'c', '00000011000000110000001100111011011001111100001111000011110000110110011100111011'=>'d', '00111100011001101100001111111111110000000110001100111110'=>'e', '00011110001100110011001100110000001100001111110000110000001100000011000000110000'=>'f' ); $string1 = ''; $string2 = ''; $string3 = ''; $string4 = ''; for($q=0;$q<count($numi1);$q++){ $string1 .= $numi1[$q]; }; for($q=0;$q<count($numi2);$q++){ $string2 .= $numi2[$q]; }; for($q=0;$q<count($numi3);$q++){ $string3 .= $numi3[$q]; }; for($q=0;$q<count($numi4);$q++){ $string4 .= $numi4[$q]; }; return $array[$string1].$array[$string2].$array[$string3].$array[$string4]; } echo "<img src='default.png'>|".captcha("default.png"); ?> Ну и скрин примера Вот и все.Надеюсь суть мне удалось передать, я не хотел расписывать сильно,да и вторая статья,ну и спать тянет.Ладно удачи в ваших продвижениях и проектах
На самом деле вы выбрали слишком простую капчу. Позиции символов известны, деформации отсутствуют, простенький шум. А слабо распознавать такие капчи (оригинал тут)? Мой вариант смотреть здесь(кстати я приложил исходные коды моей распознавалки, я думаю вам не помешает их изучить) Ну и просто почитайте мою статью: Анализ алгоритмов генерации CAPTCHA В ней я обобщенно рассматривал подход к методам защиты при генерации капчей, и способы их обхода.