Генерация изображения со случайным кодом (captcha)

Чаще всего изображения со случайным кодом (так называемая captcha) используются для защиты от флуда (автоматизированного ввода сообщений), некоторые сервисы находят им применнение в качестве раздражителя (для перехода на платный вариант). В общем, может пригодиться.
PHP код следующий:

$width = 100;				//Ширина изображения
$height = 60;				//Высота изображения
$font_size = 16;   			//Размер шрифта
$let_amount = 4;			//Количество символов, которые нужно набрать
$fon_let_amount = 30;		//Количество символов на фоне
$font = "fonts/cour.ttf";	//Путь к шрифту

//набор символов
$letters = array("a","b","c","d","e","f","g");
//цвета
$colors = array("90","110","130","150","170","190","210");

$src = imagecreatetruecolor($width,$height);	//создаем изображение
$fon = imagecolorallocate($src,255,255,255);	//создаем фон
imagefill($src,0,0,$fon);						//заливаем изображение фоном

for($i=0;$i < $fon_let_amount;$i++)			//добавляем на фон буковки
{
	//случайный цвет
   	$color = imagecolorallocatealpha($src,rand(0,255),rand(0,255),rand(0,255),100);
   	//случайный символ
   	$letter = $letters[rand(0,sizeof($letters)-1)];
	//случайный размер
   	$size = rand($font_size-2,$font_size+2);
   	imagettftext($src,$size,rand(0,45),
	   	rand($width*0.1,$width-$width*0.1),
		rand($height*0.2,$height),$color,$font,$letter);
}

for($i=0;$i < $let_amount;$i++)		//то же самое для основных букв
{
   $color = imagecolorallocatealpha($src,$colors[rand(0,sizeof($colors)-1)],
   		$colors[rand(0,sizeof($colors)-1)],
   		$colors[rand(0,sizeof($colors)-1)],rand(20,40));
   $letter = $letters[rand(0,sizeof($letters)-1)];
   $size = rand($font_size*2-2,$font_size*2+2);
   $x = ($i+1)*$font_size + rand(1,5);		//даем каждому символу случайное смещение
   $y = (($height*2)/3) + rand(0,5);
   $cod[] = $letter;   						//запоминаем код
   imagettftext($src,$size,rand(0,15),$x,$y,$color,$font,$letter);
}

$cod = implode("",$cod);					//переводим код в строку

header ("Content-type: image/gif"); 		//выводим готовую картинку
imagegif($src);

Это максимально упрощенный вариант с использованием только одного шрифта и небольшого количества символов и цветов, хотя и этого бывает достаточно, чтобы оградиться от незатейливых спамеров и флудеров.

Через HTML такое изображение вызывается стандартно:

защитный код

Пример работы:

защитный код

Скачать скрипт генерации защитного кода с полным набором символов и возможностью подключения своих шрифтов можно здесь secpic.zip

97 Комментарии “Генерация изображения со случайным кодом (captcha)

  1. Картинка хорошая, спасибо.Только объясните, пожалуйста, как принимающий скрипт узнает, что на ней нарисовано?

  2. через переменную сессии.когда генерируем изображение — $_SESSION[‘secpic’] = implode(»,$cod);когда проверяем — if($_SESSION[‘secpic’]==strtolower($_POST[‘secpic’]))

  3. в скрипте отличные буквы, мне оч понравился, а если еще и заработает у меня вообще отлично будет

  4. Спасибо. СимпотишЫне картинки. Будем ща прикручивать к фидбэку. Спасиб автору 🙂

  5. Вставляю следующий код на свою страницу:
    echo '<img src="captcha.php">';
    echo <<<HTML
    <form action="" method="post">
    Secpic: <input type="text" maxlength="4" name="secpic" /><br />
    <input type="submit" name="submit" value="Отправь меня!" />
    </form>
    HTML;
    if ($_SESSION['secpic'] == $_POST["secpic"]) {echo "Код введен правельно.";}
    Ввожу код ПРАВЕЛЬНО, но надпись "Код введен правельно." не появляется. Что делать ?

  6. У меня тоже самое, что и у DRONNY!
    Объясните плиз!

  7. в captcha.php вместо $cod = implode("",$cod); надо написать $_SESSION['secpic'] = implode('',$cod);
    выведите на экран $_SESSION['secpic'] и $_POST["secpic"], посмотрите что в них и будет вам счастье …

  8. Разобрался!
    В самое начало страницы нужно воткнуть начало сессии!
    <php? Session_start(); ?>
    <html>

  9. Эмммм. А кто подскажет.
    На Denwer капча работает нормально, а вот на сервере (CentOS)Apache не рисуется!
    В чем проблема и как можно исправить?!

  10. to CaTacLYSM: проверяйте правильность установки GD библиотеки на сервере

  11. У Вас очень простые и талантливые идеи, спасибо. Вашу captcha прикрутил на свой сайт. До этого использовал вот это: recaptcha.net/plugins/php Идея там конечно хорошая, но это использование стороннего API, а это не всегда показано и слишком уж наворочено. Если надо создать лишнею проблему пользователю, то да, если надо создать некое препятствия для спам ботов, то не подойдет. Идеален в этом случаи Ваш скрипт. Не могли бы Вы ответить мне на вопрос: как Вы отлаживаете javascript скрипты? Так смотришь скрипт, вроде все элементарно, как начнешь отладку, так темный лес. По этому, по возможности, все реализую в "серверном варианте" на PHP, по крайней мере методом "научного тыка" (ошибки ведь сразу видно) удается более менее быстро написать скрипт. Хотя возможностей того же PHP стало не хватать и надоело воровать чужие скрипты на javascript. C уважением Сергей.

  12. А есть небольшая проблема с Кешированием. У меня почему-то сессии не совпадают немного. И когда неправильно введен код, то шаблонизатор заново отображает функцию, например, регистрации, а там код тот же, что и до этого. И при этом дико несоответствуют сессии друг другу. Запаздывают примерно на одно обновление. Как это можно исправиль. Прошу прощения за сумбур.

  13. добавляй случайный GET параметр к ссылке, что-нибудь типа /captcha.php?rand=1234, чтобы браузер и прокси не кешировали.

  14. Здравствуйте ! Не совсем мне понятно, пожалуйста объясните пожалуйста для тех кто в танке, для чего надо стартовать новую сессию, если старт таковой уже прописан в Вашем скрипте… пробовал считывать переменную таким образом как написано выше: if($_SESSION['secpic'] == strtolower($_POST['pic'])) получал неправильный ответ иди Unknow wariable _SESSION['secpic']

  15. Сессию, конечно, надо только один раз стартовать там, где это логично. Скрипт из архива можно использовать "как есть", поэтому там сессия стартуется. Если получаете неправильный ответ, а особенно Unknow wariable — включайте error_reporting(E_ALL) и проверяйте правильно ли стартована сессия там, где это получаете.

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

  17. Картинки замечательные. К генератору никаких замечаний, всё работает, однако передачу значения кода с картинки через переменную сессии осуществить не удалось. Если можете, разъясните подробнее на рабочем примере "Форма+капча+обработчик формы и кода"

  18. Таки заработало! 1. Включить куки (не уверен что нужно, но читал. что без этого может не работать); 2. Удалить из браузера всю историю, куки, посещённые адреса, кеш, можно отключить кеширование страниц и т.д.(пароли оставляем:)); 3. session_star() пишем как в обработчеке формы, так и в скрипте генерации изображения. 4. Открываем "почищенный" браузер, а лучше какой-нибудь свежеустановленный альтернативный и пробуем там — должно заработать!

  19. Здравствуйте! Сделал все как тут, картинка генерируется, но проблема вот в чем: путаюсь на той же странице вывести из сессии ТЕКСТ картинки, а он выводит почему то СТАРЫЙ, а не тот который сейчас на картинке. Да и еще при первом запуске браузера он вообще бьет ошибку на строку вывода, а когда обновляю страницу то уже выводит. но выводит текст с предыдущей картинки.

  20. А вот код, как я это делаю: <p> <img src="secpic.php" alt="защитный код"> <?php $a = $_SESSION['secpic']; echo $a; ?> </p>

  21. У меня проблемка, скрипт иногда выводит на картинку одно, а в переменную сессии другое, в чём может быть дело? Кэширование точно не причем. После чистки всего, кэша, истории и кук, тестил на чистом браузере…

  22. День добрый! Присоединяюсь к Александру. Тоже самое. Бьюсь второй день. Есть несовпадение с тем, что на картинке и с тем, что выводит $_SESSION['secpic']. В этой сессионной переменной почему то всегда значение которое было на предыдущей капче. Самое интересное что значения $_SESSION['secpic'] в скрипте моем, куда вставлена проверка и в скрипте который строит саму капчу (тот что в шапке этой статьи) РАЗНЫЕ. я это выяснил, когда добавил отсылку значения $_SESSION['secpic'] к себе на е-майл. Получилось что $_SESSION['secpic'] внутри скрипта построения капчи имеет ВЕРНОЕ значение (что и на текущей картинке), а при проверке и вызове этой переменной в своем скрипте, НЕВЕРНОЕ (предыдущее значение капчи). Помогите разобраться пожалуйста!

  23. Скрипт и капча просто супер. Что бы все заработало нужно в принимающем файле вписать следующее. $a = $_SESSION['secpic']; $a = strtolower($a); $b = $_POST['test']; $b = strtolower($b); $b = trim($b); echo "В переменной а содержится: ".$a; echo "<br>"; echo "В переменной b содержится: ".$b; echo "<br>"; if ($a == $b) { echo "куль"; } else { echo "некуль"; } ?> <br><br><br> <form name="news" method="post" action="hello.php"> <img src="blocks/secpic/secpic.php" alt="защитный код" /><br> <input type="text" name="test"> <input type="submit" name="Submit" value="Изменить"> </form>

  24. Цитата: "У меня проблемка, скрипт иногда выводит на картинку одно, а в переменную сессии другое, в чём может быть дело?" Извиняюсь забыл уточнить, када писал это сообщение, что использовал русский алфавит, и вот он та даёт осечку такого типа. Как мне кажется эта проблема кроется в генераторе картинки. Где буквы в цикле перебираются. При использовании английских символов осечек нету, у меня точно. Set, на счёт вашего варианта попробую, может сканает 🙂 В чём суть моей проблемы, я хочу замутить капчу на русском, пока не решил проблему…

  25. Здравствуйте. У меня возникла такая вот проблемка. На денвере все хорошо скрипт отрабатывается и картинка выводиться, а при переносе на хостинг скрипт перестает генерировать изображение. Подскажите плиз в чем это может быть проблема.

  26. У меня вообще выводится только альтернативный текст — подключиться к файлу никак не может

  27. Подскажите как сделать поле куда вписывать код

  28. Как обновить картинку с новым кодом капTча ?

  29. Чтобы обновить изображение: <span id="captcha"><img onclick="reload(); return false;" src="sec_pic.php" alt="защитный код" style="cursor:pointer;" /></span> <script language="javascript" type="text/javascript"> function reload () { var random_value = new Date().getTime(); document.getElementById('captcha').innerHTML = '<img onclick="reload(); return false;" src="sec_pic.php" alt="защитный код" style="cursor:pointer;" />'; }; </script>

  30. Аналогичная проблема с сессией. Переменная сессии показывает предыдущее значение с картинки.

  31. в каптче сессия должна стартовать session_start(); а также сессия должна стартовать в Вашем php скрипте session_start(); в скрипте — обработчике сравниваем значения $_SESSION['secpic'] и $_POST['captcha'] if ($_POST['captcha'] != $_SESSION['secpic'] OR !$_SESSION['secpic']) echo 'error'; else echo 'good';

  32. Как перегрузить средствами php или js исходный файл(secpic.php), чтобы тот файл к которому прикручена капча не перегружался. Попробовал функцию в сообщении от 08.04.11 — не работает.

  33. не дописал 1 строку, чтобы работало нужно заменить в сообщении от 08.04 <img onclick="reload(); return false;" src="sec_pic.php" alt="защитный код" style="cursor:pointer;" /> на <img onclick="reload(); return false;" src="sec_pic.php?random_value=' + random_value + '" alt="защитный код" style="cursor:pointer;" />

  34. Автору — опишите пожалуйста как Вы реализовали проверку на ввод защитного кода "Неправильный защитный код!".

  35. Неплохо было бы автору обновить исходник и код вверху добавив к нему предоставленную возможность обнавления (очень полезная штука) но всеравно обоим авторам спс за скрипт

  36. Privet Alek, deistvitelno tvoi skript o4eni horoshii, genialnii i prostoi :). Spasibo bolishoe, ia nemnoshko ego dorobotal zdelav ego dinami4nee. Kak mne postaviti zdesi moiu dorobotku?

  37. Картинка красивая, но выложите, кто-нить, пож., полностью работающую капчу с проверкой введенного кода и обновлением капчи. Сенкс!

  38. Вообще неработает, непонятно, у меня фотрма работает вообще то даже если я вообще не введу код с картинки о_______________________О помогите 🙁

  39. Не работает, на картинке и в переменной разные символы…:((

  40. Символы на картинке и в переменной разные пока вы сеанс не перезапустите,т.к. в том же сеансе данные извлечь нельзя. Сделал свой вариант, капчу сделал ф-цией которая сразу возвращает значение кея и сохраняет картинку в гифку (имя картинки регеню по ид сессии), когда надо ф-ция вызывается, потом картинка вставляется и значение кода сразу известно.

  41. Спасибо то что нужно я немного переделал его //набор символов $letters = "aeioubcdfghjklmnpqrstvwxyz0123456789"; //а строку где идет выборка символов //случайный символ $letter = $letters{rand(0,strlen($letters)-1)}; а так то то нужно сэкономило мне время, не потомучто это сложно просто это готовое решение мне понравилось Спасибо автор!

  42. Такой вопрос: как можно увеличить контрастность выводимых символов на картинке к примеру символы в фоне покрасить черным цветом а нужные для проверки сделать поярче

  43. Цвета букв задаются как RGB тремя числами от 0 до 255. Для фона они выбираются случайно в строке 20, для основных задаются варианты потемнее в строке 11. И то и другое, естественно, можно поменять.

  44. Спасибо! Целый день искал наконец нашел, установился без проблем

  45. Можно еще и фон поменять, супер то что надо

  46. Обалденный скрипт :))) Спасибо большое автору, все просто и без гемороя!!! и главное работает :))

  47. Применил данный пример, очень доволен, спасибо. Заставить работать обновление картинки из постов от 08.04.11 и 24.04.11 не получилось Зато я сочинил еще один похожий вариант с использованием библиотеки jQuery, который заработал у меня: <div class='captcha'> <img onclick='reload()' src='secpic.php'> </div> function reload() { $(".captcha").empty(); $("<img onclick='reload()' src='secpic.php?"+ new Data().getTime() +"'/>"); }

  48. Блин криво скопировался текст, в последней строке функции надо добавить аппендТу: $("<img onclick='reload()' src='secpic.php?"+ new Data().getTime() +"'/>").appendTo(".captcha");

  49. Автор, большие благодарности за код! Работает идеально. Просто, стильно и со вкусом! Кликнул по рекламе 🙂

  50. Fatal error: Call to undefined function imagecreatetruecolor() in F:serverwwwtestcommentssecpic.php on line 14 В моем php что нету такой функции?

  51. ну так и было, GD2 не было подключено! Спасибо за скрипт!

  52. в сессии находится предыдущие значение картинки,как быть? только сравниваю не с с элементом массива post а то что введено в строку

  53. Прекрасный скрипт. Но при использовании все равно валила куча спама пока в сессии не начал передавать не сам код в открытом виде, а md5 хэш. Видимо спам боты могут считывать переменные из сессии.

  54. Скрипт супер, спасибо, единственный трабл, ввожу все правельно, а пишет Регистрация невозможна: код подтверждения введен не верно Из-за чего это?

  55. Подскажите пожалуйста. Как проверить $_SESSION['secpic'] на той же странице на которую выводим капчу (например явой). Ведь в этом случае переменная методом POST не передается и соответственно $_POST['secpic'] не существует и сравнивать переменную сессии не с чем.

  56. Кстати код выбора шрифтов из папки можно упростить и улучшить, вместо: $fonts = array(); $dir=opendir($path_fonts); while($fontName = readdir($dir)) { if($fontName != "." && $fontName != "..") { $fonts[] = $fontName; } } closedir($dir); можно сделать так: $fonts = glob('fonts/*.ttf', GLOB_NOSORT); это будет полезно например если в папке со шрифтами у вас например лежит еще и .htaccess или другие файлы, так как в таком виде скрипт будет искать и использовать только файлы .ttf а не все подряд.

  57. А для обновления именно этой капчи без перезагрузки страницы я использую этот простейший JavaScript код: <img src="secpic.php?" title="Обновить картинку" onClick="this.src = 'secpic.php?'+Math.random();"/> Не забывайте также экранировать кавычки если у вас ошибки php возникают, вот так например <img src="secpic.php?" title="Обновить картинку" onClick="this.src = 'secpic.php?'+Math.random();"/>

  58. Обратные слэши тут в комментариях вырезаются поэтому второй код без экранирования тоже))) Ну думаю разобраться сможете)

  59. Здравствуйте. А как можно передать данные случайной строки в captcha.php , или забрать оттуда , если session не используется ,отключены куки? послать их при вызове GET? captcha.php/?randstr= ? это безопасно ? по другому нельзя ?

  60. Код рабочий для тех у кого ручки не оттуда вот мной подправленный исходник <?php session_start(); echo "<img src='captcha.php' alt='защитный код' />"; echo <<<_END <form action="test.php" method="post"> Secpic: <input type="text" maxlength="4" name="secpic" /><br /> <input type="submit" name="submit" value="Отправь меня!" /> </form> _END; if (isset($_POST['secpic'])) { $secpic = $_POST['secpic']; if ($_SESSION['secpic'] == $secpic) { echo "Код введен правельно"; } else { echo "Код введен не правильно"; } } ?>

  61. А код формирования каптчи в начале каптчи стартует сесия session_start(); и дальше под конец файла меняем исходник автора на вот эту бугульму $_SESSION['secpic'] = implode("",$cod); //переводим код в строку

  62. Такая проблема-часто при регистрации или скачке файлов требуется ввести данные с картинки и тут проблема(последние несколько месяцев)-пишет текст введён не правильно(использую вай-фай): летебит, депозит и уйма других всё таже проблема, со смарта и с ноута(разные браузеры,версии винды)-всё равно, раньше вводил без осечек, только с яндекс народа вводится нормально. Кто нибудь знает решение?

  63. В конце не мешало бы еще поставить imagedestroy($src);

  64. Народ Session не обновляется, сравнение не срабатывает

  65. Не могу это приладить в Joomla 2.5. В сессии пусто. Подскажите, пожалуйста, как эту красивую штучку приладить в форму регистрации?

  66. На хосте заработало! Пришлось добавить в верху secpic.php: $mainframe =& JFactory::getApplication('site'); $mainframe->initialise(); и внизу: $s=implode('',$cod); $session =& JFactory::getSession(); $session->set('secpic', $s); $_SESSION['secpic'] =$s; Только так заработало (. Будем проверять. Автору — Спасибо!

  67. Примного благодарен за скриптик

  68. Спасибо большое за скрипт! Очень полезная вещь!

  69. Спам боты пробивают эту captch-у. Как можно защитить передачу правильного ответа от ботов?

  70. Пояснения к предыдущему комментарию: У меня пробивали не через captcha , а SQL-запросами. Проверил бесплатной программой NetSparker и нашел как боты обходят защиту код-картинка.

  71. Все красиво и удобно, только проверка правильности ввода не работает. session_start(); на обоих страничках есть. На страничке с формой значение переменной $_SESSION['secpic'] недоступно, хотя в файле sess_ID значение сохраняется. Вот содержимое: secpic|s:5:"dbsp6"; В чем дело? Вторую неделю не могу ни чего сделать.

  72. а вот бы еще REFRESH добавить надо не подскажите?

  73. ха ха. я сделал =) <img src="<?=SITE_PATH?>views/script/kartinka.php?sid=<?php echo md5(time()) ?>" id="cap_img"> <a href="#"onclick="document.getElementById('cap_img').src = '<?=SITE_PATH?>views/script/kartinka.php?sid=' + Math.random(); return false">Refresh</a>

  74. "ilma55 ха ха. я сделал =)" —————————— А проверку на правильность ввода как делаете? Ведь без этого это бесполезная вещь, хоть как ее раскрась. Что интересно, здесь-то проверка работает, специально проверил, а я не могу сделать.

  75. В smarty интегрировать не получается, может кто знает как это делается?

  76. Спасибо огромное, очень выручил своим скриптом, действительно классный 😉

  77. Вот спасибо большое за простой и красивый код. Кстати чтоб при нажатии на картинку генерировалась новая нужно всего то добавить onClick, и стиль просто для отображения руки <img src="sec_pic.php" onclick="this.src='sec_pic.php'" style="cursor:pointer;">

  78. Надо в файли генерации картинки вставить Session_start() и в самый верх вашего индексного файла (index.*) тоже самое. И всё 🙂

  79. А это обновлять картинку: <a href="javascript:void(0);" onclick="document.getElementById('capcha-image').src='captcha.php?rid=' + Math.random();">Обновить картинку</a>

  80. А еще я заменил строку записи в сессию на $_SESSION['feedback']=md5(implode('',$cod)); это чтобы зашифрованная была сразу. потом проверяем: if(trim(md5($_POST['code']))==$_SESSION["feedback"])… — а есчооооо я заметил, что при изменении размера (ширины) картинки буквы всё также толкутся у левого края. оптимально-красиво до 120px ширину делать. Возможно для красоты надо добавлять количество выводимых на картинку символов. Крутой скрипт! красивый! какже я его раньше то не замечал! 🙂

  81. Капча красивая и работает прекрасно. Спасибо!

  82. Не отображается само изображение. Только alt Я так понимаю проблема в GD2? Помогите, пожалуйста.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *