CAPTCHA.ru
Что такое CAPTCHA
Статьи
Алгоритмы
MultiSwirl
MultiWave
Примеры взлома
Проект KCAPTCHA
Ссылки
Отблагодарить
English

Программный код CAPTCHA на PHP


Системные требования

PHP, GD

MultiWave

Специально разработанный алгоритм, не задействующий никаких расширений языка PHP, кроме GD.

Искажение надписи происходит в 2 этапа:

На первом символы записываются в строку, при этом варьируются x и y-координаты каждого символа (и символы записываются максимально близко друг к другу).

На втором этапе производятся волновые искажения по осям x и у с большим количеством случайно выбранных параметров (частотой, амплитудой и фазой):

Алгоритм волнового искажения вкратце таков: проходим по всем пикселям изображения, выбираем для них предшественника, смещенного на гармоническую функцию, зависящую от координат пикселя.

Вот отрывок кода, вносящий эти волновые искажения ($img — изображение-первообраз, $img2 — результат искажения):

// случайные параметры (можно поэкспериментировать с коэффициентами):
// частоты
$rand1 = mt_rand(700000, 1000000) / 15000000;
$rand2 = mt_rand(700000, 1000000) / 15000000;
$rand3 = mt_rand(700000, 1000000) / 15000000;
$rand4 = mt_rand(700000, 1000000) / 15000000;
// фазы
$rand5 = mt_rand(0, 3141592) / 1000000;
$rand6 = mt_rand(0, 3141592) / 1000000;
$rand7 = mt_rand(0, 3141592) / 1000000;
$rand8 = mt_rand(0, 3141592) / 1000000;
// амплитуды
$rand9 = mt_rand(400, 600) / 100;
$rand10 = mt_rand(400, 600) / 100;

for($x = 0; $x < $width; $x++){
  for($y = 0; $y < $height; $y++){
    // координаты пикселя-первообраза.
    $sx = $x + ( sin($x * $rand1 + $rand5) + sin($y * $rand3 + $rand6) ) * $rand9;
    $sy = $y + ( sin($x * $rand2 + $rand7) + sin($y * $rand4 + $rand8) ) * $rand10;

    // первообраз за пределами изображения
    if($sx < 0 || $sy < 0 || $sx >= $width - 1 || $sy >= $height - 1){
      $color = 255;
      $color_x = 255;
      $color_y = 255;
      $color_xy = 255;
    }else{ // цвета основного пикселя и его 3-х соседей для лучшего антиалиасинга
      $color = (imagecolorat($img, $sx, $sy) >> 16) & 0xFF;
      $color_x = (imagecolorat($img, $sx + 1, $sy) >> 16) & 0xFF;
      $color_y = (imagecolorat($img, $sx, $sy + 1) >> 16) & 0xFF;
      $color_xy = (imagecolorat($img, $sx + 1, $sy + 1) >> 16) & 0xFF;
    }


    // сглаживаем только точки, цвета соседей которых отличается
    if($color == $color_x && $color == $color_y && $color == $color_xy){
      $newcolor=$color;     }else{       $frsx = $sx - floor($sx); //отклонение координат первообраза от целого
      $frsy = $sy - floor($sy);
      $frsx1 = 1 - $frsx;
      $frsy1 = 1 - $frsy;
      // вычисление цвета нового пикселя как пропорции от цвета основного пикселя и его соседей
      $newcolor = floor( $color    * $frsx1 * $frsy1 +
                         $color_x  * $frsx  * $frsy1 +
                         $color_y  * $frsx1 * $frsy  +
                         $color_xy * $frsx  * $frsy );
    }
    imagesetpixel($img2, $x, $y, imagecolorallocate($img2, $newcolor, $newcolor, $newcolor));
  }
}

Демонстрация: (нажмите кнопку "Обновить" рядом с картинкой для перегенерации):



Готовое решение KCAPTCHA на основе этого алгоритма



© Круглов Сергей. Опубликованные на сайте алгоритмы можно свободно использовать и модифицировать.
Система управления сайтом CAPTCHA.ru: Managee