Любой кто имеет в сети сайт, рано или поздно сталкивается с проблемой спама. Не в смысле почтового спама, а спама в гостевую книгу, форум, блог, вобщем везде, где посетители сайта могут оставлять свои сообщения. Сразу стоит сказать, что хотя и бывает, что спам рассылается вручную, т.е. живым человеком - это бывает редко, обычно это делает специальная программа, которая может: изменять свой IP адрес, распознавать каптча картинку, постить разные сообщения, отвечать на свои же сообщения, но уже под другим пользователем. И много чего еще, как говорится на каждую стандартную защиту находится программист, который сделает программу или модуль к программе и защита будет повержена.
Обычно защита от нежелательного программного постинга спама, делается с помощью каптчи, но проблема в том что в распространенных стандартных движках каптча тоже стандартна. И всегда находится заказчик, желающий проспамить те несколько миллионов форумов, где установлен стандартный форум с одной и той же картинкой защиты.
Перехожу к делу, короче говоря если хотите чтобы вас не спамили нужно делать свою уникальную каптчу. Если не можете сами программировать, наймите кого нибудь, думаю что цена в 50$ не такая высокая.
Как должна работать каптча
Встречал я в сети ресурсы, где спамеру вообще ничего не нужно было распознавать, текст написанный на картинке, в открытом виде засовывался в куки. Так делать непреемлемо, потому что данные кук, можно вытащить программно.
Встречал также ресурсы, где в куки записывали результат хеш функции md5 от строки что написана на картинке, ну эти ребята давали спамерам просто так проверку правильности распознавания, что тоже непреемлемо.
Правильно делать так, строка на картинке = str1 и строка в куках = str2, генерятся случайным образом независимо друг от друга. STR2 нужна для того чтобы передавать ее в форму в открытом виде. STR1 написана только на картинке каптча. Обе строки связаны между собой в таблице. Т.е. человек в скрытом поле формы(или куках) имеет STR2, STR1 введет с картинки, и когда форма отправится скрипту скрипт достанет из таблицы запись по STR2 и сравнит STR1 из таблицы и строку введенную пользователем.
Это было небольшое отступление от темы создание каптчи, просто нельзя делать вышеуказанные ошибки.
Делаем генератор картинок
Первое, что нужно сделать, это найти уникальный шрифт. Взял с полки диск с 1 000 000 шрифтов и вперед. Решил выбирать только из рукописных шрифтов, набралось около 20 штук.
Еще насчет шрифтов, можно использовать рандомом все 20 шрифтов, например каждый раз писать случайным фонтом все буквы. Можно каждый символ на картике писать случайно выбранным шрифтом. Я для себя решил писать всегда одним и тем же шрифтом, если начнется спаминг, просто сменю шрифт на следующий.
Теперь насчет шума. Всякие шумовые помехи встречаются почти на всех капчах. От себя скажу, из опыта программного распознавания капч, шум больше мешает человеку распознать каптчу, чем программе. Может быть поэтому на капче от гугла нет никаких шумов. Вобщем свою каптчу решил делать без шумов.
Исходный код
<?php // Тип содержимого – картинка формата PNG header("Content-type: image/png"); // создаем картинку размером 130X40 $img=imagecreatetruecolor(180, 80) or die('Cannot create image'); // заполняем фон картинки белым цветом imagefill($img, 0, 0, 0xFFFFFF); $x=0; $i = 1; $sum = ""; $fonts = array( './BIRCH_C.TTF', './CHAMPGNE.TTF', './EASTSIDE.TTF', './GISMONDA.TTF', './OLGA_C.TTF', './RIVERSDE.TTF', './SSR56__C.TTF', './STAC222N.TTF', './STEVE.TTF', './VICTORIA.TTF' ); //$font = $fonts[rand(0, sizeof($fonts)-1)]; $font = './OLGA_C.TTF'; // выводим одну цифру за один проход цикла (всего 5 цифр) while ($i++ <= 5) { // выводим текст поверх картинки imagettftext( $img, // идентификатор ресурса rand(12,25), // размер шрифта в пикселях rand(-35,35), // угол поворота текста $x=$x+30, 25+rand(0,10), // координаты (x,y), соответствующие левому нижнему // углу первого символа imagecolorallocate($img, rand(0,128), rand(0,128), rand(0,128)), // цвет шрифта $font, // имя файла со шрифтом $rnd=rand(0,9)); // случайная цифра от 0 до 9 // Собираем в одну строку все символы на картинке $sum = $sum.(string)$rnd; } //Не забудьте $sum записать в таблицу как STR1 // выводим готовую картинку в формате PNG imagepng($img); // освобождаем память, выделенную для картинки imagedestroy($img); ?>
Вот, что получилось

Вся работа заняла не более 30 минут.
Похожие статьи
Теги: Captcha, php, Капча, программирование
RSS подписка
Email подписка
October 8th, 2008 at 3:19 am
А вы можете за 50$ сделать уникальную капчу для моего форума? А то спамеры задолбали ыыы-ыы.
October 13th, 2008 at 10:29 am
Вот прочитал то что вы пишете и дошел до написания комментариев, а где у вас защита о которой вы говорите?
October 13th, 2008 at 11:00 am
Защита о которой я пишу, не на этом сайте.
Этот блог не спамят.
October 14th, 2008 at 3:40 am
на сколько сложно распознать подобную капчу: wap.klinskoe-promo.ru/scripts/kcaptcha/index.php я вотне знаю с какой стороны к ней подойти
October 14th, 2008 at 4:23 am
2 Nitrogen
Мне сложно ответить на этот вопрос, потому что
1) Мы не разглашаем алгоритмы распознавания капч
2) Распознавание не самой простой капчи, а это не простая капча - вобщем все станет понятно, когда будет сделано распознавание и будут результаты тестирования на предмет какой процент удачного распознавания.
Вообще с этим разговором лучше в аську.
November 7th, 2008 at 1:45 am
Как просто ларчик открывается то… Спасибо, заинтересовало.
Добавил удаление просроченных связок str1-str2 из базы, вполне ничего так.
Только вопрос - как повлияет, если кто-то начнёт запрашивать эту картинку несколько тысяч раз в пределах времени жизни капчи? как mysql среагирует на такого размера таблицу?
December 1st, 2008 at 11:51 am
“Решил выбирать только из рукописных шрифтов, набралось около 20 штук.”
один хрен рукописные или нет, если бы вы понимали природу проблему, то обошлись бы без таких глупостей. Насчёт 20-и штук это гораздо важнее и правильнее.
Насчёт шумов не загоняйте: если тяжело прочитать человеку, то программе нереально.
Насчёт капчи гугла: она далеко не самая крутая из всех существующих, она даже обычная и без изысков. Создатели руководствовались принципом Оккама: не мудрить а просто хорошо слепить текст и исказить его. Не обязательно считать её шедевром капч и всячески пытаться ровняться на неё.
Кстати, почему капча внизу никак не похожа на вашу?
December 1st, 2008 at 3:51 pm
2 Yuri
0) Выбирал только из рукописных шрифтов не по причине что это поможет от распознавания, просто так захотелось, из эстетических соображений.
1) Начет шумов, из личного опыта так что не обманываю. Хотя случаи бывают разные, но честное слово всего 1 раз попадалась капча, которую я как человек хорошо распознавал с шумами, а программно почистить от шумов не получилось.
2) Насчет капчи гугла. Действительно обычная без изысков, действительно есть более сложные капчи в плане эффектов, но капча гугла сложно распознаваема и это важнее.
3) Почему не похожа капча из поста на капчу-защиту этого блога. Во первых разрабатывалась для другого проекта. Во вторых установленная на блоге капча прекрасно справляется со спамерскими постами, вот если перестанет справляться вот тогда поставлю свою.
December 2nd, 2008 at 7:53 pm
0) стоило написать именно так: часто люди после прочтения подобных предложений вводятся в заблуждение и делают в дальнейшем неосмысленные действия.
1) Понятно. Хотя мне кажется что ваш вариант капчи был бы гораздо сильнее с шумами.
//$font = $fonts[rand(0, sizeof($fonts)-1)];
$font = ‘./OLGA_C.TTF’;
Здесь наверно должно быть всё наоборот
вообще последнюю строку стоило стереть перед тем, как выкладывать код на всеобщее обозрение.
rand(-35,35), // угол поворота текста
Только что красивей будет 
я бы делал например от 60 до 180, что бы 100%-но не было варианта когда угол наклона 0. А вообще (-35,35) - не достаточно: в вашем примере только с «2»-кой будут проблемы, остальные распознаются на ура любой несложной программой, потому что они практически не наклонены. Как вариант красивый для пользователя, подвергающегося проверке на вшивость, было бы хорошо, что бы угол наклона букв был бы в отрезке [-180,-60]+[60,180]. Например вместо «rand(-35,35)» написать «60+ rand(0,240)», но это если соответствующая функция вывода текста «понимает» угол наклона более 180-и градусов. Правда такой интервал не самый удачный из-за 6-ки и -9ки.
Цвет текста делать рандомным на самом деле смысла нету, всё равно программы для распознавания не привязываются ни к каком определённому цвету. Капча внизу и гугла в пример
Ну и лучше 10-ю символами не ограничиваться: ещё и буквы добавить. Сами символы лучше делать поменьше, чем они мельче тем больше проблем при распознавании.
В общем как-то получился слабоватый вариант из-за мелких недочётов, которые в сумме серьёзно ослабили защиту от взлома. Мне кажется что ваша программа по распознаванию с такой капчей бы справилась.
December 8th, 2008 at 12:31 pm
2Yuri
0) Хорошо учитель, теперь перед тем как опубликовать чтолибо на своем блоге буду страшивать у ваСC совета, о сенсей
1) Насчет поворотов, большие углы поворота конечно помогают от побитового сравнения, (алгоритм побитового сравнения самое первое что я написал для распознавания каптч). Короче не знаю как у кого, но моему алгоритму распознавания глубоко побарабану под каким углом повернут символ.
Насчет кода
//$font = $fonts[rand(0, sizeof($fonts)-1)];
$font = ‘./OLGA_C.TTF’;
оставил так специально, чтобы человек понимающий мог легко сделать проблемы спамерам. Если еще $font = $fonts[rand(0, sizeof($fonts)-1)]; засунуть в цикл while, тогда каждый символ на картинке будет выведен своим шрифтом, об этом написано в тексте поста.
И вообще есть старое программистское высказывание на критиков программ. Применяли его на критиканов Windows. Им говорили ну не нравится тебе виндовс напиши свою, покажи что Ты сам что-то можешь
Короче предлагаю каптча дуэль. Оба делаем каптчи. Шрифт использовать можно только один. Шумы любые. Искажения любые. Исходниками и шрифтами меняемся. Делаем капчераспознавалки. Тестируем на 2000 картинок каждый алгоритм у кого больше результат тот и победил. Или как вариант для определения победителя устанавливаем скрипты на сайт кто больше аккаунтов за 1 час нарегит тот и победитель.
Подробности в аську 220889768
January 10th, 2009 at 8:33 am
2 e64f:
День бобрый. Пара вопросов:
1) А как влияет различный цвет символов на распознавание?
2) Почему бы не зарегить строку с каптчой в переменных сессии?
January 28th, 2009 at 4:49 am
2 S10
1) Различный цвет символов по разному влияет на распознавание, обычно в распознавании первый этап это приведение рисунка к двухцветному, по возможности чтобы черные точки принадлежали символу. По крайней мере в первых своих алгоритмах я делал так, и до сих пор это во многих случаях прокатывает. Таким образом если у вас цвет символа, совпадает с цветом шумового элемента возможно это ухудшит ситуацию с программным распознаванием.
2) Можно хранить и в переменной сессии, можно в базе данных, можно в текстовом файле. Хранить в базе данных мне кажется наиболее правильным и удобным.
February 3rd, 2009 at 12:28 pm
2 e64f:
Спасибо за советы.
“…Таким образом если у вас цвет символа, совпадает с цветом шумового элемента…”
Можно тогда считать двухцветную каптчу (белый фон, хорошо искажённые чёрные символы с чёрными точками как шум) достаточно близкой к идеалу
February 3rd, 2009 at 2:12 pm
2 S10
Черные точки как шум очень легко убираются.
Если хотите пришлите мне вашу картинку, я могу оценить насколько она устойчива к взлому, говорить лучше через аську
February 22nd, 2009 at 10:57 pm
я тоже хотел бы чтобы вы оценили мою капчу. запостил картинку с следующем посте(ибо прочел его раньше)
March 3rd, 2009 at 2:38 pm
Капча капче рознь