Разработка CAPTCHA своими руками

    Сегодня, благодаря господам спам-ботам и иже с ними, в сети практически невозможно что-либо сделать без ввода символов со сгенерированного изображения — CAPTCHA (далее — капча). Фактически, это предотвращает выполнение какого-либо скрипта без участия человека, и в этом топике я расскажу, как такую капчу создать средствами PHP, а так же упомяну очень полезный топик другого хабраюзера, который пригодится при разработке изображения-капчи.

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

    Основные правила


    При разработке капчи нужно обязательно соблюдать несколько основных правил:

    1. Капча создана для людей
    Она должна сходу читаться, но не в ущерб стойкости к распознаванию. Очень наглядный пример капчи, не соблюдающей это правило — изображение справа.

    2. Генератор капчи должен быть четко ограничен в используемых символах
    Наглядный пример — изображение в начале топика. Конечно, reCAPTCHA — чудесное изобретение, но порой она предлагает ввести символы, которые и в charmap найти сложно. Кстати, когда речь идет о капче с использованием кириллических символов — ни в коем случае генератор не должен использовать букву «ё». Лично я знаю много людей, у которых на ~ (тильда / ё) повешено какое-то действие в системе.

    3. Капча должна быть стойкой к распознаванию
    … но не в ущерб читаемости. Вообще, этот пункт — самый сложный во всей разработке. Необходимо найти золотую середину — капча сходу читается людьми и вообще (насколько возможно) не читается ботами. Так же необходимо учитывать специфику ресурса, на котором планируется использовать капчу, и его контингента. Если речь идет о, допустим, форуме читающих домохозяек за сорок, то на стойкость капчи можно плюнуть с высокой башни — никому он не упрется. Если речь идет о, например, имейджборде, то тут нужна капча а-ля вырвиглаз.

    Проектирование


    В качестве теоретического объекта, для которого мы будем делать капчу, выступит сферический форум в вакууме, с умеренно агрессивными, умеренно умными и вообще умеренными пользователями. В разработке такой капчи нам поможет очень полезный топик от хабраюзера Pastafarianist. А именно я обращу внимание на перечисленные недостатки и достоинства взятых им капчей.

    Итак, по порядку перечислим, что же мы можем использовать:

    1. В изображении должно использоваться хотя бы несколько цветов. Желательно всегда разные


    Изображение выше — пример того, как это выглядит в действии. На самом деле, это не очень надежный вариант, так как текст с фоном очень контрастирует. Разберемся с цветами позже.

    2. Должен присутствовать шум


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

    3. Буквы должны находиться на небольшом расстоянии друг от друга


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

    4. Размеры символов должны быть разными


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

    5. Отвратительный шрифт


    Очень полезный способ. Засечки, курсив, стилизация — отличные подводные камни для бота. Так же в сочетании с шумом в виде линий очень хорошо будет смотреться тонкий шрифт. Если абстрагироваться от первого правила генерации капчи, то можно использовать множество шрифтов сразу, к примеру свой шрифт для каждого символа.

    6. Символы под случайным углом



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

    7. Динамические искажения



    Ничего ужаснее человечество еще не придумало. Искажения в капче зачастую очень сильно снижают читаемость человеком. Разумеется, это достаточно эффективно против ботов, но это так же эффективно и против людей. Главное — не перестараться, искажения должны быть незначительными.

    Итак, что же мы сделаем:
    — Контрастный фон, с шумом
    — Линии за текстом, линии на тексте
    — Текст в случайном положении
    — Количество символов будет случайным, от 4 до 7
    — Размер каждого символа будет случайным
    — Цвет текста каждый раз будет случайным
    — Символы будут слегка прикасаться
    — Каждый символ будет под случайным небольшим углом

    Разработка


    Определимся с целью:
    — Генерация шума
    — Генерация текста
    — Форма с возможностью обновления капчи
    — Обработчик введенных данных
    По мере написания статьи понял, что искажения в данном случае абсолютно неуместны. Для тех, кому они все же нужны — в конце топика ссылка на урок по созданию искажений.

    Пишем форму

    <form action="go.php" method="post" enctype="multipart/form-data">
    <!-- Форма будет отправлять введенные пользователем данные скрипту go.php методом POST -->
    <img src='captcha.php' id='capcha-image'>
    <!-- Сама капча -->
    <a href="javascript:void(0);" onclick="document.getElementById('capcha-image').src='captcha.php?rid=' + Math.random();">Обновить капчу</a>
    <!-- Ссылка на обновление капчи. Запрашиваем у captcha.php случайное изображение.  -->
    <span>Введите капчу:</span>
    <input type="text" name="code">
    <input type="submit" name="go" value="Продолжить">
    <!-- Отправляем данные скрипту-обработчику go.php -->
    </form>
    

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

    Пишем генератор кода капчи (random.php)

    <?php
    
    // Функция генерации капчи
    	function generate_code() 
    	{    
    		  $chars = 'abdefhknrstyz23456789'; // Задаем символы, используемые в капче. Разделитель использовать не надо.
    		  $length = rand(4, 7); // Задаем длину капчи, в нашем случае - от 4 до 7
    		  $numChars = strlen($chars); // Узнаем, сколько у нас задано символов
    		  $str = '';
    		  for ($i = 0; $i < $length; $i++) {
    			$str .= substr($chars, rand(1, $numChars) - 1, 1);
    		  } // Генерируем код
    
    		// Перемешиваем, на всякий случай
    			$array_mix = preg_split('//', $str, -1, PREG_SPLIT_NO_EMPTY);
    			srand ((float)microtime()*1000000);
    			shuffle ($array_mix);
    		// Возвращаем полученный код
    		return implode("", $array_mix);
    	}
    ?>
    

    Тут все ограничивается только вашим воображением. Как-то я видел иной способ — выбиралась текущая минута, час, месяц, все это перемножалось, из этого выбирались 10 случайных символов, дважды извлекался MD5-хеш, из него извлекались 6 случайных символов и затем все это еще и перемешивалось. Кстати, обратите внимание на выбранные мною символы — я исключил такие как i, l, 1 и 0, o, c, из-за того, что они слишком похожи друг на друга, в некоторых ситуациях пользователь может ошибиться. Генератор я назвал random.php (далее он будет запрашиваться в других скриптах).

    Пишем генератор изображения (captcha.php)

    <?php
    // Устанавливаем переменную img_dir, которая примет значение пути к папке со шрифтами и (если потребуется) изображениями
    define ( 'DOCUMENT_ROOT', dirname ( __FILE__ ) );
    define("img_dir", DOCUMENT_ROOT."/captcha/img/"); // Если скрипт отказывается работать, то скорее всего ваш сервер не поддерживает $HTTP_SERVER_VARS. В таком случае, закомментируйте эту строчку и раскомментируйте следующую.
    // define("img_dir", "/captcha/img/");
    
    // Подключаем генератор текста
    include("random.php");
    $captcha = generate_code();
    
    // Используем сессию (если нужно - раскомментируйте строчки тут и в go.php)
    // session_start();
    // $_SESSION['captcha']=$captcha;
    // session_destroy();
    
    // Вносим в куки хэш капчи. Куки будет жить 120 секунд.
    $cookie = md5($captcha);
    $cookietime = time()+120; // Можно указать любое другое время
    setcookie("captcha", $cookie, $cookietime);
    		
    // Пишем функцию генерации изображения
    function img_code($code) // $code - код нашей капчи, который мы укажем при вызове функции
    {
    	// Отправляем браузеру Header'ы
    		header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");                   
    		header("Last-Modified: " . gmdate("D, d M Y H:i:s", 10000) . " GMT");
    		header("Cache-Control: no-store, no-cache, must-revalidate");         
    		header("Cache-Control: post-check=0, pre-check=0", false);           
    		header("Pragma: no-cache");                                           
    		header("Content-Type:image/png");
    	// Количество линий. Обратите внимание, что они накладываться будут дважды (за текстом и на текст). Поставим рандомное значение, от 3 до 7.
    		$linenum = rand(3, 7); 
    	// Задаем фоны для капчи. Можете нарисовать свой и загрузить его в папку /img. Рекомендуемый размер - 150х70. Фонов может быть сколько угодно
    		$img_arr = array(
    						 "1.png"
    		);
    	// Шрифты для капчи. Задавать можно сколько угодно, они будут выбираться случайно
    		$font_arr = array();
    			$font_arr[0]["fname"] = "DroidSans.ttf";	// Имя шрифта. Я выбрал Droid Sans, он тонкий, плохо выделяется среди линий.
    			$font_arr[0]["size"] = rand(20, 30);				// Размер в pt
    	// Генерируем "подстилку" для капчи со случайным фоном
    		$n = rand(0,sizeof($font_arr)-1);
    		$img_fn = $img_arr[rand(0, sizeof($img_arr)-1)];
    		$im = imagecreatefrompng (img_dir . $img_fn); 
    	// Рисуем линии на подстилке
    		for ($i=0; $i<$linenum; $i++)
    		{
    			$color = imagecolorallocate($im, rand(0, 150), rand(0, 100), rand(0, 150)); // Случайный цвет c изображения
    			imageline($im, rand(0, 20), rand(1, 50), rand(150, 180), rand(1, 50), $color);
    		}
    		$color = imagecolorallocate($im, rand(0, 200), 0, rand(0, 200)); // Опять случайный цвет. Уже для текста.
    
    	// Накладываем текст капчи				
    		$x = rand(0, 35);
    		for($i = 0; $i < strlen($code); $i++) {
    			$x+=15;
    			$letter=substr($code, $i, 1);
    			imagettftext ($im, $font_arr[$n]["size"], rand(2, 4), $x, rand(50, 55), $color, img_dir.$font_arr[$n]["fname"], $letter);
    		}
    
    	// Опять линии, уже сверху текста
    		for ($i=0; $i<$linenum; $i++)
    		{
    			$color = imagecolorallocate($im, rand(0, 255), rand(0, 200), rand(0, 255));
    			imageline($im, rand(0, 20), rand(1, 50), rand(150, 180), rand(1, 50), $color);
    		}
    	// Возвращаем получившееся изображение
    		ImagePNG ($im);
    		ImageDestroy ($im);
    }
    img_code($captcha) // Выводим изображение
    ?>
    

    Весь код максимально закомментирован. Для проверки введенной капчи обработчиков вносим ее хэш в куки. Для выбора шрифта и фона я сделал массивы, что бы можно было засунуть туда десяток шрифтов и десяток фонов, каждый раз выбираться будут случайные. Шрифт выбрал Droid Sans, он тонкий и среди шума плохо заметен. Кстати, в данном случае я выбрал ужасный, отвратительный и контрастный фон, демонстрация будет в конце топика. К моему удивлению, на читаемость человеком это не повлияло, шрифт достаточно хорошо выделяется, не смотря на то, что цвет шрифта выбирается из случайного пикселя на фоне.

    Пишем обработчик (go.php)

    <META http-equiv=content-type content="text/html; charset=UTF-8">
    <?php
    include("random.php");
    
    $cap = $_COOKIE["captcha"]; // берем из куки значение MD5 хэша, занесенного туда в captcha.php
    
    // Пишем функцию проверки введенного кода
    function check_code($code, $cookie) 
    {
    
    // АЛГОРИТМ ПРОВЕРКИ	
    	$code = trim($code); // На всякий случай убираем пробелы
    	$code = md5($code);
    // НЕ ЗАБУДЬТЕ ЕГО ИЗМЕНИТЬ!
    
    // Работа с сессией, если нужно - раскомментируйте тут и в captcha.php, удалите строчки, где используются куки
    //session_start();
    //$cap = $_SESSION['captcha'];
    //$cap = md5($cap);
    //session_destroy();
    
    	if ($code == $cap){return TRUE;}else{return FALSE;} // если все хорошо - возвращаем TRUE (если нет - false)
    	
    }
    
    // Обрабатываем полученный код
    	if (isset($_POST['go'])) // Немного бессмысленная, но все же защита: проверяем, как обращаются к обработчику.
    	{
    		// Если код не введен (в POST-запросе поле 'code' пустое)...
    			if ($_POST['code'] == '')
    			{
    				exit("Ошибка: введите капчу!"); //...то возвращаем ошибку
    			}
    		// Если код введен правильно (функция вернула TRUE), то...
    			if (check_code($_POST['code'], $cookie))
    			{
    				echo "Ты правильно ввел капчу. Возьми с полки тортик, он твой."; // Поздравляем с этим пользователя
    			}
    		// Если код введен неверно...
    			else 
    			{
    				exit("Ошибка: капча введена неверно!"); //...то возвращаем ошибку
    			}
    		}
    	// Если к нам обращаются напрямую, то дело дрянь...
    	else 
    	{
    		exit("Access denied"); //..., возвращаем ошибку
    	}
    	
    ?>
    

    Тут все предельно ясно. Берем куки, записанную ранее в captcha.php, берем введенный код, точнее его хэш и сравниваем. Внимание! Если планируете пользоваться этим кодом, не забудьте изменить алгоритм проверки.

    Результат



    Результат получился весьма неплохим, полностью оправдав мои ожидания (прошу, пожалуйста, заметить, что я не ставил себе цель сделать непробиваемую капчу). Протестировать на стойкость его можно вот тут (надеюсь, мой сервак не упадет под хабраэффектом).
    На самом деле, мой код — это лишь шаблон, над которым вы можете издеваться как угодно. А еще на самом деле это не нужно — есть reCaptcha, но лично мне доставило удовольствие делать этот скрипт, пока делал прочитал гору документации, надеюсь, что кто-нибудь подчерпнет знания из моего топика :)

    Footer


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

    Не кидайтесь помидорами, пожалуйста :) Это мой первый технический топик на хабре.
    И да, я не имею понятия, каким образом работают современные капчи, я просто и не искал никакой информации на эту тему. Если мои методы кажутся вам индийскими — прошу немедленно написать об этом в ЛС / комментарии, я с удовольствием почитаю :) Из недостатков моего метода я вижу только то, что если в браузере не включены куки, то через эту капчу не пройти.
    Метки:
    Поделиться публикацией
    Похожие публикации
    Комментарии 98
    • 0
      Она должна сходу читаться, но не в ущерб стойкости к распознаванию. Очень наглядный пример капчи, не соблюдающей это правило — изображение справа.

      Это вы называете сходу читаться? Да тут в лучшем случае только 50% можно сходу прочесть. А остальные нужно долго разглядывать и гадать, то ли это o+t, толи a+i, а может o+l. Терпеть немогу эту капчу гугла.
      • +5
        Читайте внимательнее :)
        Она должна сходу читаться, но не в ущерб стойкости к распознаванию. Очень наглядный пример капчи, не соблюдающей это правило — изображение справа.
        • 0
          Да, к сожалению именно это «НЕ» и не заметил. Но написаного уже не сотрешь :)
        • +5
          И да, полностью с вами согласен насчет гугловской капчи. Хочется найти ее разработчика и ударить его.
          • +2
            гугловская капча (recaptcha) — это слова из книг которые не смог распознать парсер гугла. А гугл лишь добавляет искажения(размеры букв, наклон и тп). Так что разработчик тут не причем
            • +3
              recaptcha и капча в гугловых сервисах — это разные вещи, хоть и от одной компании
            • 0
              Ваш вариант? Где можно посмотреть? Только мигом, а то я спешу ;))
            • 0
              А мне нравится капча с вводом символов мышкой. Порядок символов из 6-8 знаков тоже тяжело правильно ввести роботу, зато человеку гораздо проще.

              А вообще, суперпараноидальные капчи спокойно «высчитываюся» индийскими сервисами, где сидят полмиллиарда идийцев и спокойно распознают(ся) (за минимальные деньги)
              • +1
                Когда такие сервисы только начали появляться, то я попробовал этим позарабатывать, в первый день открытия одного такого. Расценок не было, говорили, что вот-вот добавят. День и ночь я убил на это, грохнулся спать (потирая руки). Когда проснулся, обнаружил, что мой заработок составляет $0.7. Какое же это было разочарование.
                Я себе представить не могу человека, который упорно трудится и «зарабатывает» на этом деньги.
                • 0
                  Это у вас с непривычки получилось 0.7$ :)
                  На хлопковых плантациях Индии, индиец зарабатывает 2$ в день, где 0.75$ — ночлег и плюс 0.5 у.е. питание. Вот кто будет упорно трудится за 2$ в день. Лучше спокойно в офисе рзгадывать капчи, чем под палящем солноцем собирать хлопок.
                  Так что мы еще «жируем». Богатый бедного не поймет :)
            • +17
              Ваша капча распознается с использованием самых тривиальных техник, потому что:
              • Все буквы одного цвета
              • Линии «шума» — одного цвета и этот цвет не совпадает с цветом букв.
              • «Шум» на фоне отсеивается просто по цвету соседних пикселей
              • +11
                Странно, что кусок комментария обрезался.
                Определить пару цветов — букв и линий «шума» можно обычной гистограммой.
                Отделить цвет букв от цвета линий можно анализом пиков на гистограммах, построенных по столбцам изображения.
                Закрасить повреждения на буквах можно просто анализом соседних цветов.
                В итоге получаем черные буквы на белом фоне — разрезаем по вкусу и распознаем.
                • +1
                  Видимо, я слишком увлекся идеализацией капчи в начале топика, потому, что я особо на это не обращал внимания на это когда писал код :) Цель была не сделать непробиваемую капчу, а показать, как она вообще делается средствами PHP.
                  Но я полностью согласен, вот такая капча читается, но ничто не мешает поправить ее в коде, ибо комментарии есть чуть ли не к каждой строчке.
                  • 0
                    Добавлю.
                    Следующие вещи можно менять в коде просто подправив значения:
                    — Шрифт
                    — Фон
                    — Размер шрифта
                    — Положение капчи
                    — Расстояние между символами
                    — Угол поворота символов
                    — Шум (цвет, положение, количество)
                    — Разница в положении символов по Y
                    Просто это все надо балансировать, очень аккуратно менять эти значения. Топик создан лишь в образовательных целях, вряд ли кто-то будет пользовать эту капчу на практике :)
              • +3
                Капчи нынче распознаются не ботами, а людьми. Существуют сервисы decaptcher.com, captchabot.com, antigate.com и им подобные.
                Программно же распознаются достаточно простые капчи, где процент пробива достаточно высок, всё остальное идёт через сервисы по распознаванию.
                • +13
                  В запросе подменяем куки captcha на md5(«31337») и полю code POST-данных присваиваем значение «31337».
                  Вывод: не храните важных данных на стороне пользователя, используйте сессии.
                  • –8
                    Неверное суждение. В данном конкретном случае — да, так вполне можно пробиться через капчу, но ведь легко можно заметить, что этот алгоритм запросто меняется в go.php. Я могу трижды извлечь MD5, из него SHA-1, из получившегося значения беру от 7 до 32 символов с конца, опять извлекаю MD5 ну и так далее.
                    Надо комментировать эту фичу, да, спасибо за наводку.
                    • +4
                      Это не оправдание использование дурного подхода.
                      • –5
                        Но задумывалось именно так :)
                        Подход не дурной, просто надо уметь его готовить.
                        • +1
                          Ок — пруфлинки рекомендации использовать данный подход хоть от одного более-менее авторитетного человека?
                          • +1
                            Хорошо, я не хочу ни с кем спорить :)
                            Добавил закомментированные строчки для работы с сессиями.
                      • +4
                        Хоть 100500 раз шифруйте закрытым ключом длиной 100500 бит (при условии что он не меняется), рано или поздно будет набрана статистика капча -> кука. Куки на клиенте не должны зависеть от капчи, для этого можно использовать либо стандартные сессии, либо какой-то свой механизм хранения соответствия капчи от независящей от неё куки, POST- или GET-параметра. Самый простой способ «в лоб» — таблица в БД с двумя полями: поле id — монотонно возрастающий или случайный первичный ключ капчи, передаваемый в форму и поле value — значение капчи. Но это, имхо, оверхид — достаточно любого key-value хранилища даже не гарантирующего персистентность, лишь бы минут 5 (или сколько в среднем требуется для заполнения формы) хранил при вашей нагрузке. В PHP для этого есть сессии, можно использовать шаред мемори, можно кэш акселлераторов, можно memcache, но сессии самое простое и очевидное решение.
                        • 0
                          Вы видимо не поняли, как вы будете шифровать не важно, главное в том, что ключ лежит в куках, достаточно один раз считать его и угадать каптчу вручную, и потом всё время отправлять эту же пару ключа и угаданной каптчи, ваш скрипт будет ее принимать. Нужно обязательно хранить в сессии, чтобы нельзя было отправить одну и ту же каптчу дважды.
                      • +2
                        только матан, только хардкор :)
                        • +5
                          image
                          • 0
                            была идея написать о таком, но мне стало так влом писать генератор для матан-капчи. я себе даже не представляю, как его сделать.
                            • +3
                              Первое, что приходит в голову — ТеХ + искажатели.
                              • 0
                                Можно генерировать строку типа integrate(sin(2x)+x^8^0.5), делать запрос к wolframalpha.com и тырить оттуда картиночку с преобразованной строкой.

                                www.wolframalpha.com/input/?i=integrate%28sin%282x%29%2Bx^8^0.5%29

                                Вот отсюда, например.
                                • 0
                                  Написал генератор, написал топик, но опубликовать не получается…
                                  Генерит вот такое:
                                  Работает на PHP+GD.
                                  • 0
                                    Ну тут нужно просто составные символы разобрать. А всё остальное сделают сервисы типа WolframAlpha.

                                    Тыц!
                                    • 0
                                      Ну с лурковскими пределами можно поступить точно так же. Тут главное — оригинальность =)
                                  • 0
                                    Такие выражения может вычислять Maxima.
                                    Кроссплатформенное консольное приложение.
                                    Причём ответ может выдать даже в виде алгебраического выражения.
                                  • НЛО прилетело и опубликовало эту надпись здесь
                                    • –1
                                      Слабоватая капча — предел считается в уме на пару секунд. Надо чтоб был сложный дифур, с кучей граничных условий :)
                                  • +7
                                    За 5 минут написал скрипт, который делает с этой капчей вот так:
                                  • +5
                                    шум и полоски элементарно убираются любым высокочастотным фильтром. так что роботу пофиг, а человеку — вырвиглаз.
                                    полоски поверх букав зачастую не дают прочитать буквы.
                                    и вообще, выделить тут основной цвет букв — проще пареной репы, потом отфильтровать другие цвета — элементарно. так что зачем все эти пляски — не понятно.

                                    прежде чем писать капчу я бы рекомендовал сначала потренироваться с ее взломом. тогда придет понимание какие преобразования усложняют распознавание (например, те, которые усложняют сегментацию), а какие нет (например высокочастотный цветной шум).
                                    • 0
                                      Не увидел в данном примере простой читабельной каптчи, например каптча от проекта KCaptcha выглядит весьма читабельнее: image

                                      Да и одной каптчи уже недостаточно, сервисам по распознаванию не имеет значение, что распознавать.
                                      • 0
                                        5bayp
                                        • +18
                                          image
                                          • –7

                                            Спасибо за поднятое настроение!
                                            • 0
                                              А причем тут Ruby On Rails?
                                              • +1
                                                Возможно дефект речи, для него ROR и LOL одно и тоже?:) p.s. Adiost не в одиду, just4fun
                                                • 0
                                                  Подозреваю, тут обыгрывается факт, что у китайцев и, кажется, японцев большие проблемы с произношением звука «л» — они говорят его ближе к «р».
                                                  Просто у них в языке звука «л» в европейском виде нет, они не приучены.
                                                  • 0
                                                    У китайцев есть Л, нету у японцев. Однако же бытует ошибочное мнение, что у китайцев его тоже нет.
                                          • 0
                                            ККэптча от настроек сильно зависит. Если наклон и изгиб сильно варьируются и есть небольшое наслаивание букв, то иногда тоже читать тяжко
                                          • +2
                                            После проверки капчи нужно удалить cookie / запись в сессии, поскольку можно один раз вручную правильно ввести капчу, после чего бот может использовать это же самое значение с теми же cookie / сессией.
                                            • –3
                                              после подгрузки капчи куки меняется.
                                            • +1
                                              Очень мало капчестроителей уделяют свое внимание этой проблеме.
                                              Очень много кап в своей жизни я обошел именно этим способом. Один раз распознал сам и далее использовал плоды своего разума :)
                                            • +1
                                              $DOCUMENT_ROOT = $_SERVER["DOCUMENT_ROOT"];
                                              define("img_dir", $DOCUMENT_ROOT."/captcha/img/");


                                              не лучше ли сделать так?:

                                              define ( 'DOCUMENT_ROOT', dirname ( __FILE__ ) );
                                              define("img_dir", DOCUMENT_ROOT."/captcha/img/");


                                              $_SERVER[«DOCUMENT_ROOT»] на поддоменах будет криво работать
                                              • 0
                                                Спасибо, подправил :)
                                                • 0
                                                  Что-то у вас какой-то странный стиль именования констант. То большими буквами, то маленькими. Это опечатка или он несет какой-то сакральный смысл?
                                                • +2
                                                  Так много букв, а результат не интересно взламывать :(
                                                  А вообще за статью спасибо.
                                                  • +2
                                                    Лично я знаю много людей, у которых на ~ (тильда / ё) повешено какое-то действие в системе.
                                                    А как эти люди набирают слова, где «ё» требуется? Например, я живу на улице Константина Царёва, а не Ца́рева.
                                                    • 0
                                                      alt+241 например
                                                      • +3
                                                        Экий гемморой из-за желания занять тильду.
                                                    • +1
                                                      Основы php на Хабре.
                                                      Ну да ладно, если кому интересно, вот www.webcheatsheet.com/PHP/create_captcha_protection.php
                                                      !How to Create CAPTCHA Protection using PHP and AJAX!
                                                      • +2
                                                        Как по мне — так сегоднящнии капчи создают больше неудобств для пользователя, нежели для бота. ИМХО
                                                        Нужно чтото более легче для юзера и сложнее для бота. Например собрать пазл из 10ти частей или еще что-то интересней…
                                                        • +1
                                                          Согласен с Вами.
                                                          Captcha в виде текста, который надо набрать абсолютно не отвечает требованиям юзабилити. Да, это стандартный для разработчиков способ, но он ставит преграды (порой непреодолимые) перед обычными пользователями.
                                                          В интернете достаточно примеров, как можно обойтись без классической капчи, эти примеры демонстрируют творческий подход разработчиков к решению задачи и заботу о своих пользователях.
                                                          Конечно, многое зависит от задачи, которую Вы решаете.
                                                          • 0
                                                            Как вариант капча с подсказкой :) Ввод символов мышкой с виртуальной клавиатуры. Последовательность 8 символов тоже не очень будет удобна для робота, даже если он будет знать какие символы. (1*2*3*4*5*6*7*8=40320)

                                                            А вот человеку гораздо легче. Да я думаю и на 5-6 робот с вероятностью 99.999% будет промахиваться (если конечно подсунуть «правильную» капчу с шумом, наклонами и т.п.

                                                            Правда любая капча ломается миллиардом индийских программистов.
                                                        • 0
                                                          Ещё можно как капчу использовать нечто вроде habrahabr.ru/blogs/subconsciousness/16281/ (gif-ку с анимацией сделать)
                                                          • 0
                                                            Обрывки математических формул в рекапче в последнее время встречаю всё чаще.
                                                            • 0
                                                              А теперь напишите распознаватель Вашей каптчи — в процессе появятся мысли как её усовершенствовать :-)
                                                              • +1
                                                                очень хороший пример как не надо делать капчи.
                                                                получилась легко распознаваемая, вызывающая рвотный рефлекс своим видом поделка. хранение в куке на стороне клиента — верх идиотизма.

                                                                ты хоть понимаешь, что не важен какой адгоритм, если мы можем повторно использовать куку. в примере с сессией у тебя тоже ошибка, после проверки значение сессии должно сразу после извлечения ансетиться, чтобы никто посторно не воспользовался тем же кодом. в твоём случае достаточно достаточно единожды запросить картинку. а дальше просто формировать руками $_POST с нужным единожды сгенерированным.
                                                                • –1
                                                                  Забыл :) Исправил, вроде бы. Торопился когда код для сессии писал, убегать надо было.
                                                                  Насчет рвотного рефлекса — опять же, я не заморачивался с этим. При помощи этого кода можно вполне себе симпатичную вещь сделать.
                                                                • 0
                                                                  Никогда мне не нравились эти буквенные капчи. Неужели человека от робота отличает только способность разбирать чей-то кривой почерк? Для каждого проекта нужно искать свой уникальный способ фильтрации спама. Универсальные средства давно имеют универсальные контрметоды.

                                                                  На SmashingMagazine в начале марта была отличная статья на тему различных подходов к реализации теста Тьюринга: coding.smashingmagazine.com/2011/03/04/in-search-of-the-perfect-captcha/

                                                                  P.S. Собирался перевести статью на русский, но на середине остановился, и все никак не соберусь =)
                                                                  • 0
                                                                    Я ее читал кстати. И тоже была мысль перевести, сейчас руки зачесались это сделать. Вы не против, или все таки планируете закончить?
                                                                    • 0
                                                                      Пожалуй, уступлю Вам. =) У меня сейчас объективно на это времени нет, а статья действительно полезна и интересна сообществу. Так что терпения и усидчивости Вам! ;)
                                                                      • 0
                                                                        Благодарю, постараюсь порадовать переводом как можно скорее!
                                                                  • +2
                                                                    Посмотрел демо.
                                                                    «Ты правильно ввел капчу. Возьми с полки тортик, он твой.»
                                                                    Ненавижу, когда мне вот так открыто со страницы тыкают незнакомые люди.
                                                                    Все-таки, мы в интернете, давайте уважать друг друга.
                                                                    • –1
                                                                      Ой да ладно, всяко лучше, чем какое-нибудь пресное сообщение типа «Капча введена верна». Но на будущее учту :)
                                                                      • 0
                                                                        Всяко лучше? Не согласен.
                                                                        • 0
                                                                          Хорошо, искренне извиняюсь за подобную фамильярность, такого больше не повторится :)
                                                                          Исправил в скрипте.
                                                                    • –4
                                                                      Согласно нетикету в интернете все на «ты», если что.
                                                                      • +1
                                                                        Ага, расскажите еще.
                                                                        Почему-то практически на всех сайтах обращаются на «вы», например «введите пароль», «сохраните настройки», «скачайте файл».
                                                                        Скажите Гуглу, что он не шарит в нетикете, пусть он вам напишет «Привет! Ты забыл пароль! Хочешь восстановить его?», а потом «Ура, ты восстановил пароль, теперь можешь взять с полки тортик».
                                                                        Абсурд.
                                                                        • 0
                                                                          Где об этом сказано, кстати?
                                                                        • 0
                                                                          Скайп вот тыкает. Раздражает.
                                                                        • +4
                                                                          Лично я знаю много людей, у которых на ~ (тильда / ё) повешено какое-то действие в системе.
                                                                          Появление консоли Quake что ли? ;)
                                                                          • 0
                                                                            Почти так и есть, правда я использую alt + ` для вызова guake.
                                                                          • 0
                                                                            При написании своей капчи на php мождно использовать удобные классы Zend Framework-а для работы с ней. Благо в ZF можно использовать отдельные компоненты библиотеки совершенно автономно.
                                                                            Там есть класс Zend_Captcha, там автоматически генерируется кодовое слово, рендерятся различные виды шума (точки, палочки) и т.д. Все это гибко настраивается, наследуешься от него и все. Он тоже, кстати, на gd работает.
                                                                            • +1
                                                                              Всего за 1$ на anti-captcha.net индусы распознают 1000 любых капч.
                                                                              • 0
                                                                                логинился на хабр, не с первого раза ввел пароль. Вырвал глаз от капчи. Грустно.
                                                                                • 0
                                                                                  Кстати, про капчу, что вначале статьи (от recaptcha), главное ввести правильно второе слово. Вместо первого можно ввести всё что угодно.
                                                                                  • 0
                                                                                    А потом в один день вы не сможете решить капчу потому-что кто-то написал абракадабру =)
                                                                                  • +1
                                                                                    Статьи о защите капч от разгадывания ботом мне кажутся как с другой планеты. Кому надо писать распознавалку для каждого из сотен типов капч, если на капчаботе и т.д. стоимость разгадывания 1000 капч стоит… 1$ с попаданием 85-90%

                                                                                    Если капчу может разгадать «индус» с такого сервиса, значит сабмит защищенной ей формы можно осуществлять автоматически. Фактически, капча защищает только от ленивого программиста, не более.
                                                                                    • 0
                                                                                      Простые математические пока ещё надёжны (если специально не ломятся). Порою бывает достаточно просто поменять имена полей местами (ну и переменных конечно), или же заполнять скрытое поле javascript'ом. При виде извращений на подобии уже нечитаемых recaptcha, не что комментировать не хочется, порою и на регистрацию (большинство даже значения полей сбрасывают) времени тратить не хочется.
                                                                                      • 0
                                                                                        Попробовал каптчу, только с третьего раза смог прочитать что написано :)
                                                                                        • 0
                                                                                          У меня на форуме была простая текстовая капча с одним вопросом «Какого цвета небо?»
                                                                                          Ни один спамбот её не смог взломать, а пользователи были избавлены от необходимости разбирать искажённый хаотичный набор букв с картинки.
                                                                                          • 0
                                                                                            хабракарма.рф
                                                                                            • 0
                                                                                              Капча — треугольник, перевернутый труегольник, квадрат, круг, треугольник. Это картинки.
                                                                                              Дальше рядом картинка (треугольник и перевернутый треугольник — «треугольник») квадрат — «квадрат», круг — «круг».
                                                                                              Вопрос — напишите названия символов из капчи через запятую, как указаны в подсказке. Вот картинкаimage
                                                                                              Ну и конечно, же жесть для автоматизированного перебора — 3 ввода — бан по ip на 5 минут, через 3 ввода — бан увеличивается в 2 раза и так далее. От ручного ввода ничего не спасет, если вы не будете усложнять распознавание капчи реальными пользователями.
                                                                                              • 0
                                                                                                другой вариант, тоже легко распознаваемый — image
                                                                                                • 0
                                                                                                  Вариант, которые используется конкретными сайтами со специфичской тематикой. Вместо капчи задаётся вопрос, который касается темы сайта. Главное делать подобное нечувствительным к регистру (+ указать все известные варианты написания (сокращённо и нет (если название)) в качестве ответа)

                                                                                                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.