Создание каптчи своими руками на PHP

Создание каптчи своими руками на PHP

Создание каптчи своими руками на PHP

Мы все с вами привыкли видеть на сайтах при заполнении любой формы трудночитаемую картинку с рандомными символами и цифрами. Данная картинка называется КАПТЧА (от CAPTCHA — англ. C ompletely  A utomated  P ublic  T uring test to tell  C omputers and  H umans  A part  — полностью автоматизированный публичный тест Тьюринга для различения компьютеров и людей). Как описано в расшифровке аббревиатуры данная картинка позволяет определить робот или человек заполняет форму.

В настоящее время существует множество разновидностей КАПТЧ, это может быть картинка с рандомным текстом, или картинка с математическими действиями, блок картинок в которых нужно выбрать определенные предметы и т.д. Все эти картинки направлены на борьбу с роботами спамерами, которые заполняют формы автоматически.

Стоит понимать что КАПЧА это не панацея, и при желании ее всегда можно распознать автоматически использую соответствующие сервисы. Данная проблема актуальна для высоконагруженных веб сайтов с большой аудиторией, например социальные сети или популярные доски объявлений такие как Авито и т.д.

Переходя от вступления к практики, для написания КАПТЧИ нам понадобится библиотека GD. GD Graphics Library (GD) — программная библиотека, написанная Томасом Баутелом ( Thomas Boutell ) и другими разработчиками для динамической работы с изображениями. Данная библиотека работает с множеством других языков программирования и служит для работы с графикой. Как вы уже догадались, мы будем с помощью библиотеки GD и PHP создавать свою картинку с рандомным текстом. Graphics Library позволяет также редактировать существующие изображения, а именно наложение логотипа на картинку, изменения размеров загружаемого изображения и многое другое.

Список функция для работы с графикой в PHP

  • gd_info — Вывод информации о текущей установленной GD библиотеке
  • getimagesize — Получение размера изображения
  • getimagesizefromstring — Получение размера изображения из строки данных
  • image_type_to_extension — Получение расширения файла для типа изображения
  • image_type_to_mime_type — Получение Mime-типа для типа изображения, возвращаемого функциями getimagesize, exif_read_data, exif_thumbnail, exif_imagetype
  • image2wbmp — Выводит изображение в браузер или пишет в файл
  • imageaffine — Return an image containing the affine transformed src image, using an optional clipping area
  • imageaffinematrixconcat — Concatenate two affine transformation matrices
  • imageaffinematrixget — Get an affine transformation matrix
  • imagealphablending — Задание режима сопряжения цветов для изображения
  • imageantialias — Требуется ли применять функции сглаживания или нет
  • imagearc — Рисование дуги
  • imagechar — Рисование символа по горизонтали
  • imagecharup — Рисование символа вертикально
  • imagecolorallocate — Создание цвета для изображения
  • imagecolorallocatealpha — Создание цвета для изображения
  • imagecolorat — Получение индекса цвета пиксела
  • imagecolorclosest — Получение индекса цвета ближайшего к заданному
  • imagecolorclosestalpha — Получение индекса цвета ближайшего к заданному с учетом прозрачности
  • imagecolorclosesthwb — Получение индекса цвета, имеющего заданный тон, белизну и затемнение
  • imagecolordeallocate — Разрыв ассоциации переменной с цветом для заданного изображения
  • imagecolorexact — Получение индекса заданного цвета
  • imagecolorexactalpha — Получение индекса заданного цвета и альфа компонента
  • imagecolormatch — Делает цвета палитровой версии изображения более соответствующими truecolor версии
  • imagecolorresolve — Получает идентификатор конкретного цвета или его ближайший аналог
  • imagecolorresolvealpha — Получает идентификатор конкретного цвета и альфа компонента или его ближайший аналог
  • imagecolorset — Установка набора цветов для заданного индекса палитры
  • imagecolorsforindex — Получение цветов, соответствующих индексу
  • imagecolorstotal — Определение количества цветов в палитре изображения
  • imagecolortransparent — Определяет цвет как прозрачный
  • imageconvolution — Наложение искривляющей матрицы 3х3, используя коэффициент и смещение
  • imagecopy — Копирование части изображения
  • imagecopymerge — Копирует часть изображения с наложением
  • imagecopymergegray — Копирует часть изображения с наложением в градациях серого
  • imagecopyresampled — Копирование и изменение размера изображения с ресемплированием
  • imagecopyresized — Копирование и изменение размера части изображения
  • imagecreate — Создание нового палитрового изображения
  • imagecreatefromgd2 — Создание нового изображения на основе GD2 или URL
  • imagecreatefromgd2part — Создание нового изображения на основе части GD2 файла или URL
  • imagecreatefromgd — Создание нового изображения на основе GD файла или URL
  • imagecreatefromgif — Создает новое изображение из файла или URL
  • imagecreatefromjpeg — Создает новое изображение из файла или URL
  • imagecreatefrompng — Создает новое изображение из файла или URL
  • imagecreatefromstring — Создание нового изображения из потока представленного строкой
  • imagecreatefromwbmp — Создает новое изображение из файла или URL
  • imagecreatefromwebp — Создает новое изображение из файла или URL
  • imagecreatefromxbm — Создает новое изображение из файла или URL
  • imagecreatefromxpm — Создает новое изображение из файла или URL
  • imagecreatetruecolor — Создание нового полноцветного изображения
  • imagecrop — Crop an image using the given coordinates and size, x, y, width and height
  • imagecropauto — Crop an image automatically using one of the available modes
  • imagedashedline — Рисование пунктирной линии
  • imagedestroy — Уничтожение изображения
  • imageellipse — Рисование эллипса
  • imagefill — Заливка
  • imagefilledarc — Рисование и заливка дуги
  • imagefilledellipse — Рисование закрашенного эллипса
  • imagefilledpolygon — Рисование закрашенного многоугольника
  • imagefilledrectangle — Рисование закрашенного прямоугольника
  • imagefilltoborder — Заливка цветом
  • imagefilter — Применяет фильтр к изображению
  • imageflip — Flips an image using a given mode
  • imagefontheight — Получение высоты шрифта
  • imagefontwidth — Получение ширины шрифта
  • imageftbbox — Определение границ текста выводимого шрифтом freetype2
  • imagefttext — Нанесение текста на изображение, используя шрифты FreeType 2
  • imagegammacorrect — Применение гамма коррекции к GD изображению
  • imagegd2 — Вывод GD2 изображения в браузер или файл
  • imagegd — Вывод GD-изображения в браузер или в файл
  • imagegetclip — Get the clipping rectangle
  • imagegif — Выводит изображение в браузер или пишет в файл
  • imagegrabscreen — Захватывает изображение с экрана
  • imagegrabwindow — Захватывает изображение окна
  • imageinterlace — Включение или выключение интерлейсинга
  • imageistruecolor — Определяет, является ли изображение полноцветным
  • imagejpeg — Выводит изображение в браузер или пишет в файл
  • imagelayereffect — Установка флага альфа сопряжения для использования эффектов наложения изображений
  • imageline — Рисование линии
  • imageloadfont — Загрузка шрифта
  • imagepalettecopy — Копирование палитры из одного изображения в другое
  • imagepalettetotruecolor — Converts a palette based image to true color
  • imagepng — Вывод PNG изображения в браузер или файл
  • imagepolygon — Рисование многоугольника
  • imagepsbbox — Выдает параметры рамки, обрамляющей текст написанный шрифтом PostScript Type1
  • imagepsencodefont — Изменение вектора кодировки шрифта
  • imagepsextendfont — Растягивание или сжатие шрифта
  • imagepsfreefont — Освобождение памяти, занятой шрифтом PostScript Type
  • imagepsloadfont — Загрузка шрифта PostScript Type 1 из файла
  • imagepsslantfont — Наклон шрифта
  • imagepstext — Рисование текста поверх изображения, используя шрифты PostScript Type1
  • imagerectangle — Рисование прямоугольника
  • imagerotate — Поворот изображения с заданным углом
  • imagesavealpha — Установка флага сохранения всей информации альфа компонента (в противовес одноцветной прозрачности) и сохранение PNG изобаржения
  • imagescale — Scale an image using the given new width and height
  • imagesetbrush — Установка изображения (кисти), посредством которого будут рисоваться линии
  • imagesetclip — Set the clipping rectangle
  • imagesetinterpolation — Set the interpolation method
  • imagesetpixel — Рисование точки
  • imagesetstyle — Установка стиля рисования линий
  • imagesetthickness — Установка толщины линий
  • imagesettile — Установка изображения, которое будет использовано в качестве элемента мозаичной заливки
  • imagestring — Рисование строки текста горизонтально
  • imagestringup — Рисование строки текста вертикально
  • imagesx — Получение ширины изображения
  • imagesy — Получение высоты изображения
  • imagetruecolortopalette — Преобразование полноцветного изображения в палитровое
  • imagettfbbox — Получение параметров рамки обрамляющей текст написанный TrueType шрифтом
  • imagettftext — Рисование текста на изображении шрифтом TrueType
  • imagetypes — Возвращает список типов изображений, поддерживаемых PHP сборкой
  • imagewbmp — Выводит изображение в браузер или пишет в файл
  • imagewebp — Output a WebP image to browser or file
  • imagexbm — Вывод XBM изображения в браузер или файл
  • iptcembed — Встраивание двоичных IPTC данных в JPEG изображение
  • iptcparse — Разбор двоичных IPTC данных на отдельные тэги
  • jpeg2wbmp — Конвертирует изображение из формата JPEG в WBMP
  • png2wbmp — Преобразование PNG файла в WBMP

Определим требования к нашей КАПТЧе для ее реализации:

  • Размер холста 200 х 60
  • Фон холста RGB(255, 181, 181)
  • Шрифт verdana.ttf
  • Рандомные лини на холсте с рандомным цветом
  • Генератор строки для КАПТЧИ
  • Рандомный цвет символов и углом наклона
  • Рандомное количество и цвет точек на холсте
  • Обновление КАПТЧИ без перезагрузки страницы (Jquery)
  • КАПТЧА чувствительна к регистру
  • Плашка с URL нашего сайта

Приступаем к написанию КАПТЧИ. Первое что нам нужно – это генератор случайных чисел. Такой генератор я писал в одной из статей Генератор пароля + соль в пароле для хранения в MySQL . Так же необходимо загрузить файл шрифта на сервер для использования его в КАПТЧе.

Создаем файл captcha.php

  
    <?php
    /**
    * КАПТЧА 1.0
    * Site: https://bezramok-tlt.ru
    * Создание КАПТЧИ своими руками
    * Autor: Админ
    */

    //Запускаем сессию
    session_start();

    //Устанавливаем кодировку и вывод всех ошибок
    header('Content-Type: text/html; charset=UTF-8');
    error_reporting(E_ALL);

    function getRandString($num)
    {
        //Генерим массив из букв
        $letter = range('a', 'z');
        //Генерим массив из цифр
        $number = range(0, 9);

        //Создаем строку с маленькими и большими буквами и цифрами
        $letter = implode('',$letter);
        $letter = $letter.strtoupper($letter).implode('',$number);

        //Строка с генерированым кодом
        $randStr = '';
        for ($i = 0; $i < $num; $i++){
            //Прогоняем циклом столько, сколько нужно символов в строке
            $randStr .= $letter[rand(0, strlen($letter) - 1)];
        }
        return $randStr;
    }

    //Функция генерации цвета
    function randColor($imgPng, $red = null, $green = null, $blue = null)
    {
        if(is_numeric($red) and is_numeric($green) and is_numeric($blue))
            return imagecolorallocate($imgPng, $red, $green, $blue);
        else
            return imagecolorallocate($imgPng, rand(0, 255), rand(0, 255),rand(0, 255));
    }

    //Путь до нужного шрифта
    $fonts = "./font/verdana.ttf";

    //Нижняя плашка каптчи
    $url = "http://bezramok-tlt.ru";

    //Размер шрифта каптчи
    $fontSize    = 24;
    $fontSizeUrl = 12;

    //Размеры холста холста
    $width  = 200;
    $height = 80;

    //Количество линий и пикселей на холсте
    $countLine = rand(0, 10);
    $countPixel = rand(200, 1000);

    // Сколько символов будем выводить на картинке
    $numbers = 5;

    //Получаем сгенерированую строку
    $randStr = getRandString($numbers);

    // Записываем каптчу в сессию
    $_SESSION['captcha'] = $randStr;

    // Создаем картинку (холст) размером 200 X 60
    $imgPng = imagecreatetruecolor($width, $height);

    // Создаем фон холста, RGB(255, 181, 181)
    $imgColor   = randColor($imgPng, 255, 181, 181);

    //Зададим цвет линиям, у меня он динамический
    $lineСolor  = randColor($imgPng);

    //Зададим цвет для точек, у меня он динамический
    $pixelСolor = randColor($imgPng);

    //Цвет текста, у меня он динамический
    $textColor  = randColor($imgPng);

    //Цвет полоски с текстом в низу картинки
    $bgColor  = randColor($imgPng, 0, 0, 0);

    //Цвет текста URL красный
    $redColor  = randColor($imgPng, 255, 0, 0);

    //Определяем фон картинки
    imagefilledrectangle($imgPng, 0, 0, $width, $height, $imgColor);

    //Создаем линии на холсте
    for ($i = 0; $i < $countLine; $i++) {
        imageline($imgPng, 0, rand(0, $height), $width, rand(0, $height), $lineСolor);
    }

    //Создаем точки на холсте
    for ($i = 0; $i < $countPixel; $i++) {
        imagesetpixel($imgPng, rand(0, $width) , rand(0, $height), $pixelСolor);
    }

    //Пишем по букве не холсте
    for ($i = 0; $i < strlen($randStr); $i++)
    {
        //Растояние между символами
        $x = ($width - 20) / strlen($randStr) * $i + 10;

        //Случайное смещение
        $x = rand($x, $x + 4);

        //Координата Y
        $y = $height - (($height - $fontSize) / 2 );

        //Случайны цвет отдельного символа
        $letterColor = randColor($imgPng);

        //Случайный угол наклона символов
        $angle = rand(-25, 50);

        //Пишем текст на холсте (наш код каптчи)
        imagettftext($imgPng, $fontSize, $angle, $x, $y, $letterColor, $fonts, $randStr[$i]);
    }

    // создаем рамку для текста
    $bbox = imagettfbbox($fontSizeUrl, 0, $fonts, $url);

    //Высчитываем координаты для выравнивания по центру
    $textX = $bbox[0] + (imagesx($imgPng) / 2) - ($bbox[4] / 2);

    //Определяем фон картинки
    imagefilledrectangle($imgPng, 0, 60, $width, $height, $bgColor);

    //Надпись с URL
    imagettftext($imgPng, $fontSizeUrl, 0, $textX, 75, $redColor, $fonts, $url);


    // Посылаем заголовок серверу о том что у нас картинка в формате png
    header("Content-type: image/png");
    imagepng($imgPng);

    //Освобождаем
    imagedestroy($imgPng);

    ?>
  

Результат работы скрипта

Если обратиться к этому файлу через браузер, то мы получим вот такую картинку.

Создание каптчи bezramok-tlt.ru

Создаем файл с разметкой form.html

    
      <!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">   
    <meta charset="UTF-8">
    <!-- Latest compiled and minified CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    <title>Document</title>
</head>
<body>
    <div class="container">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <h1 class="text-center">Форма работы каптчи:</h1>
                <!-- Выводим ошибки -->
                <?php 
                    if(count($err) > 0)
                        echo '<div class="alert alert-danger">'. implode('<br>', $err).'</div>';
                    
                    if(!empty($ok))
                        echo '<div class="alert alert-success">'. $ok .'</div>';

                ?>
                <form method="POST" action="">
                  <div class="form-group">
                    <label for="exampleInputEmail1">Email</label>
                    <input type="email" class="form-control" id="exampleInputEmail1" name="email" placeholder="Email">
                  </div>
                  <div class="form-group">
                    <label for="code">Код с картинки</label>
                    <input type="text" class="form-control" id="code" name="captcha" placeholder="Код с картинки">
                  </div>
                  <div class="form-group">
                    <p class="help-block"><img id="captcha" src="captcha.php" alt=""> <button class="btn btn-default" id="refreshImg"><span class="glyphicon glyphicon-refresh" aria-hidden="true"></span></button></p>

                  </div>
                  <button type="submit" class="btn btn-primary" name="send">Отправить</button>
                </form>
            </div>
        </div>
    </div>
<script src="http://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
<script>
    $(document).ready(function(){

        $('#refreshImg').click(function(e){
            e.preventDefault();
            $('#captcha').attr('src', 'captcha.php?r=' + Math.random());
        })
    });
</script>
</body>
</html>
    
  

Создаем файл обработчик формы index.php

    
      <?php
      /**
      * Главный файл
      * Site: http://bezramok-tlt.ru
      * Создание КАПТЧИ своими руками
      */

      //Запускаем сессию
      session_start();

      //Устанавливаем кодировку и вывод всех ошибок
      header('Content-Type: text/html; charset=UTF8');
      error_reporting(E_ALL);

      //Инициализируем переменные для работы
      $err = array();

      //Если нажата кнопка отправки формы
      if(isset($_POST['send'])){
          //Утюжим пересенные
          if(!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL))
            $err[] = 'Не верный email!';

          if($_SESSION['captcha'] != $_POST['captcha'])
            $err[] = 'Код с картинки не совпадает!';

          if(empty($err))
            $ok = 'Вы прошли проверку!';
      }

      //Подключаем наш шаблон
      include './form.html';
      ?>
    
  

Скачать: Создание каптчи своими руками на PHP


Теги
Поддержи проект:

No-name
я заметил
Привет, админ, сделай новый урок, система друзей, то есть что бы можно было добавить друг друга в друзья, принять отклонить, оставить его в подписках, как вк.

14/03/2017 23:57:06

Администрация
Администрация

Мне кажется, что данная тема очень узко направленная и не всем интересна. Так что не стоит ждать в ближайшее время.

17/03/2017 09:52:37

No-name
я заметил
Админу привет, такой вопрос пробую поставить твою капчу и мне не удается это сделать правильно, она установилась, но когда ввожу числа, мне всегда говорят что я ввел не правильно ее. Где может быть моя ошибка?

10/03/2017 11:04:41

Администрация
Администрация

Посмотри что ты отправляешь на сервер в POST

echo '<pre>';
print_r($_POST);
echo '</pre>';

10/03/2017 12:02:30

No-name
я заметил
О уже перезалил) Отлично) Может поможешь мне? если не сложно, пожалуйста!

07/10/2016 14:52:49

Администрация
Администрация

Вечером поймай меня. Пока на работе.

07/10/2016 14:53:48

No-name
я заметил
Админ перезалей файл, С Уважением к разработчику! И еще одно как сделать мне тоже обновить капчу? В моей капче?

07/10/2016 14:41:24

Администрация
Администрация

Привет, перезолил.

В шаблон в ставь где каптчу нужно вывести:

<img src="captcha.php" alt="capthca">

07/10/2016 14:52:58


Copyright © 2014 - 2024 All rights reserved.