PHP

индекс
206,76

Каптча 3d

Прочитав топик RapidShare — новые каптчи, я вспомнил как слушал доклад создателя каптчи на UaВебе.
Зайдя на сайт, желая посмотреть код, я увидел :
Q: Is it opensource?
A: No, sorry. Maybe later.
Я удивился! Мне казалось что любой маломальски образованный хороший программист сделает такую каптчу.
Погуглив и нашел пару интересных линков: 1, 2 и не получил кода, решил написать сам :) .
:00 С чего начать? Вспоминая времена университета, линейный анализ (ее у меня вел класный препод ) и подумав что както нежно сделать с 3D -> 2D, а это как я помню называется "проекция", я набрал это слово в строку поиска
:03 Пройдя по цепочке ссылок в Википедии и прочитав подходящую статью я решил что мне подойдет изометрическая проекция
:05 Ну вот главная формула есть
изометрическая проекция
:15 пару строк кода и вот первая 3D картинка
Piccy.info - Free Image Hosting
:16 два цикла и
Piccy.info - Free Image Hosting
:20 выведу текст и используя его как патерн для z оси получаем
Piccy.info - Free Image Hosting
:30 добавим шума и синусоид получим
Piccy.info - Free Image Hosting

Скорость частота отрисовки 31.42 [#/sec] на Intel Core 2 Duo 2.2 GGz php 5.2.6 Apache 2.2.4 on Win Vista Sp1

/**
*
* @author Andrii Kasian
*/

$capthca 
= new Capthca3d();
$capthca->render();


class 
Capthca3d{
    const 
CHARS 'WEafRTYIPAGHJKXBNM3479j';
    
protected $hypot 8;
    
protected $image null;
    
    
protected $text '';
    
    
public function __construct()
    {
        
$this->time microtime(true);
        
$this->generateCode();
    
    }
    
protected function generateCode()
    {
        
$chars self::CHARS;
        for(
$i =0$i<3$i++){
            
$this->text .= $charsmt_rand(0,22)};
        }
    }
    
    
public function getText()
    {
        return 
$this->text;
    }
    
protected function getProection($x1,$y1,$z1)
    {
        
$x $x1 $this->hypot
        
$y $z1 $this->hypot;
        
$z = -$y1 $this->hypot;
        
        
$xx 0.707106781187
        
$xy 0;
        
$xz = -0.707106781187
        
        
$yx 0.408248290464
        
$yy 0.816496580928
        
$yz 0.408248290464;
        
        
$cx $xx*$x $xy*$y $xz*$z;
        
$cy $yx*$x $yy*$y $yz*$z20 $this->hypot;
        return array(
            
'x' => $cx,
            
'y' => $cy
            
); 
    }
    
    function 
zFunction($x,$y){
        
$z imagecolorat($this->image,$y/2,$x/2)>0?2.6:0;
        if( 
$z != ){
            
$z += mt_rand(0,60)/100;
        }
        
$z += 1.4 sin(($x+$this->startX)*3.141592654/15)*sin(($y+$this->startY)*3.141592654/15);
        return 
$z;
    }
    
public function render()    
    {
        
$xx =30;
         
$yy =60;
        
         
$this->image imageCreateTrueColor($yy $this->hypot  $xx $this->hypot);
        
        
$whiteColor imageColorAllocate($this->image,255,255,255);
        
imageFilledRectangle($this->image,0,0,$yy $this->hypot  $xx $this->hypot,$whiteColor);
        
        
$textColor imageColorAllocate($this->image,0,0,0);
        
imageString($this->image530$this->text$textColor);
        
        
         
$this->startX mt_rand(0,$xx);    
         
$this->startY mt_rand(0,$yy);
        
         
$coordinates = array();
         
        for(
$x 0$x $xx 1$x++){
            for(
$y 0$y $yy 1$y++){
                
$coordinates[$x][$y] = $this->getProection($x,$y,$this->zFunction($x,$y));
             }
         }
         
        for(
$x 0$x $xx$x++){
            for(
$y 0$y $yy$y++){
                 
$coord = array();
                 
$coord[] = $coordinates[$x][$y]['x'];
                 
$coord[] = $coordinates[$x][$y]['y'];
                 
                 
$coord[] = $coordinates[$x+1][$y]['x'];
                 
$coord[] = $coordinates[$x+1][$y]['y'];
                 
                 
$coord[] = $coordinates[$x+1][$y+1]['x'];
                 
$coord[] = $coordinates[$x+1][$y+1]['y'];
                 
                 
$coord[] = $coordinates[$x][$y+1]['x'];
                 
$coord[] = $coordinates[$x][$y+1]['y'];
                
                
$c = (int) ($this->zFunction($x,$y)*32);
                
$linesColor imageColorAllocate($this->image$c$c$c);
                
imageFilledPolygon($this->image$coord4$whiteColor);
                
imagePolygon($this->image$coord4$linesColor);
             }
         }
        
        
$textColor imageColorAllocate($this->image,0,0,0);
        
imageString($this->image530$this->text$whiteColor);
        
imageString($this->image130, (microtime(true)-$this->time), $textColor);
        
header('Content-Type: image/png');
        
        
imagepng($this->image);
        
imagedestroy($this->image);
    }
}
П.С.: GPL
+132
29 июня 2008, 22:11
137

комментарии (102)

НЛО прилетело и опубликовало эту надпись здесь
+2
kvladimir #
Шантаж - именно это слово сразу пришло и мне в голову.
+7
cachealot #
> П.С.: желающие получить код могут написать его сами (это очень просто) или добавить мне кармы (что намного сложнее, ее нужно иметь) , при 20+ я его выложу
>Кармашантаж? Это что-то новенькое.

отдаю код за +15 кармы ))))
0
cachealot #
кстати это все на правах рекламы (c)

ps очень надеюсь тут люди с юмором
0
KF_NEXUS #
А что же делать бедным несчастным людям с кармой < 5 не понимающим смысл этой формулы?
0
HeadFore #
Идти учиться в универ. Это на первом курсе проходят.
0
KF_NEXUS #
Я в данный момент абитуриент =)
0
Great #
обычная матричная алгебра
0
sdmitry #
Вам выбор дали. Пишите сами раз не нравятся условия.
+3
nForce #
«Шантаж» звучит как-то вульгарно, мне больше нравится «вымогательство» ©
+2
yvanko #
Скорее, кармабазар. Или, "Программирую за карму"
0
nForce #
Это цитата, из "Футурамы" :)
+14
Leon478 #
Хорошая статья, понравилось. Пожалуй, попробую такую штуковину реализовать на досуге.

P.S. Пожалуй, без карматоргов Вы бы и так заработали свою двадцатку, а так — сомневаюсь.
+8
modaz #
на счет кармы правильно. за опенсоурс нужно платить, даже больше чем обычно..
а то привыкли обормоты все на шару получать, потом еще ногами пинать за то что сахарной пудрой не присыпали и вишенку не положили
0
Reterius #
По-моему, он наоборот, наберет -20 кармы за такой пост (я не минусовал) :)
Сам пост то, в принципе, интересный, но вот, как тут выразились, "кармашантаж" - это бред :)
Тем более, тут много программистов и кому надо - такую штуку тоже сделают, а посте про RapidShare в комментариях уже предложили как эту каптчу разгадывать, так что - неэффективно.
НЛО прилетело и опубликовало эту надпись здесь
+3
Leon478 #
Автор написал: "31 штука в секунду".
НЛО прилетело и опубликовало эту надпись здесь
0
kvladimir #
Автор, будьте добры, поделитесь кодом и будет вам счастье! ;)
+5
beanime #
Да ладно вам.. что вам кармы жалко для человека?
Он же не за хухры-мыхру просит.. такая работа достойна поощрения.

Хотя вымогать действительно некрасиво) - выкладывай давай)
–3
trident #
Бессмысленный пост, но автор молодец. Здорово. Жалко, что у меня карма ниже плинтуса, и нечего ставить :)
+24
ecl #
я бы вам поставил плюс и за топик и в карму(никогда не жалел и с удовольствием поощеряю все новое), вы бы получили свое если бы не вот это:
код могут написать его сами (это очень просто) или добавить мне кармы (что намного сложнее, ее нужно иметь) , при 20+ я его выложу
вы получаете здесь информацию безвоздмездно, так почему же ваш пост на других условиях?
Исходя из этого топику поставил плюс, а вам минус, и даже извиняться не буду — по моему мнению "заслужили".

PS: http://code.google.com/p/3dcaptcha/downl…

–1
MrTiM #
Что плохого в "кармашантаже"?
Мне видится это зарождением новой тенденции скорее.
Хотите чтоб за вас реализовали описанное в коде? - Заплатите за это кармой. Все честно.

...like in real life.
0
ecl #
>>...like in real life.
если для вас это нормально, то оставайтесь людьми хотя бы тут
0
victor_lavrenko #
парень — умный. и даже если он ошибся (а он поймет, в чем ошибка), то это не дает Вам права его оскорблять.
0
MrTiM #
И всеже считаю это весьма оригинальным вымогательством и потому не понимаю почему попросить кармы за готовое решение не есть хорошо. Странно что вы восприняли чужое мнение как абсолютно неприелимое.
Прямой "шатнаж" и впрямь выглядит грубо, но суть...
0
ecl #
все-все, очень жаль что столь очевидные вещи сказываются на моей карме, поэтому ребятки я в сторону, а мои строчки перечитайте(я никого не оскорблял и не собирался, а лишь говорил о человечности, как автора так и mrtim).
0
MrTiM #
Just4justice: карму вам не снижал.
"Нет ничего более очевидного чем субъективная реальность" (с) MrTiM;)
+1
MrTiM #
К тому же описание же дано бесплатно
0
xsash #
хм. ну вот, пару запросов чтото _подобное_ по теме.
пример
http://dmtsoft.ru/captcha/dmtCaptcha_v1.2/form.php

качать с http://dmtsoft.ru/bn/428/as/oneaticleshablon/ "DMT Hard Captcha v1.0"
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
0
object #
накрутите на тор набор и 8-10 символов, обозначив первый например размером, остальные будут читаться по ХЧС, получится неплохая капча
+1
Infthi #
о, а я два года назад рисовал ленту мёбиуса, можно на ней капчу нарисовать ^_^
openGL к php прикручивается? :)
+2
object #
я не знаю, я ваще дизайнер, мимо проходил просто)
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
–1
object #
кстати я и не говорил, что надо будет вручную рисовать, все легко считается (логику придумать легко, остальное за прогерами)
0
object #
у вас неправильное представление о дизайнерах)
+1
dio77 #
А у кого оно правильное?
НЛО прилетело и опубликовало эту надпись здесь
0
GRuff #
всегда думал, что дизайнер - это тот кто делает удобно и эффективно. я ошибался?
+1
shiko_1st #
Тор, который можно вертеть, поставлялся еще в составе комплекта программ-примеров для Quick Basic четвертой версии ;-)
0
ScorpLeX #
Еще год назад научились на bigmir.net распознавать такую картинку.
Так что использовать не советую.
0
rtm #
Apatch поправте
0
egorF #
Заюзаем:)
–6
Estate_Fredda #
автор - убейся
0
coldFlame #
30 запросов формы в секунду и сервер ляжет на отрисовке капчи? Круто.
0
ecl #
их можно кэшировать :D, вариации из трех букв быстро закончатся
0
globik #
Неа, не прокатит =) Он добавляет "шума и синусоид".
0
foff4ik #
Ну я как понимаю можно неплохо ускорить скорость отрисовки, например отказавшись от зашумлений по оси z а также предварительно можно нагенерировать сколько угодно капчей
0
foff4ik #
upd: ну и в крайнем случае можно по частям заставить генерировать капчи самих поьзователей ...
0
coldFlame #
зачем отказываться, если можно предрасчитать матрицу шумов эдак на мегапиксель и ее по случайному смещению накладывать.
0
foff4ik #
Но тут же вроде красиво и правильно, и как вижу еще с отсечением заднего плана :)
В рапиде например смещение по оси z поменьше, и зашумления только сдвигом в 2d
+1
coldFlame #
отсечение заднего плана, видимо, делается отрисовкой залитых полигонов на переднем.
0
l2k #
Просто необходимо оптимизировать процесс. Имхо, я могу написать капчу, которая с помощью pure-PHP (используя только заполнение точками) будет генерить тоже самое и возможно быстрее, чем у автора :)

p.s. Оптимизировал когда-то Воксельный ландшафт, который на P-200 шел со скорость 30 fps с разрешением 640x480 ;). Так что, упрощая формулы расчёта и используя средства GD можно добиться очень высокой работоспособности. Тем более средств для этого (в том числе, как вы предлагали, кеширования скринов) существует масса.
Например, генерить для пользователей капчу раз в 2-3 секунды, либо за каждый написанный пост.
НЛО прилетело и опубликовало эту надпись здесь
0
mr_idiot #
Новый веб-сервер под названием "Apatch 2.2.4" улыбнул :)
0
skazkin #
да-да=)
0
foff4ik #
Хоть и сам могу это написать, но плюсанул,
в детстве еще за Z80 писал программку для интерактивного вращения шарика самым интересным был вывод всех формул на уровне знанаий 7-го - 8-го класса.
Ну и также ограничения по памяти и скорости , кажется дошел при вменяемом быстродействии только до сотни.

ЗЫ:Хотелось бы побольше таких статей на хабре.
–2
Estate_Fredda #
ЗЫ: хотелось бы, но без прозьб про карму!
+5
foff4ik #
Да ну что вы как дети малые, человек бы и сам получил за эту статью более чем 20 пунктов, а из за одного слова его готовы чуть ли не на костре сжечь, он дал ведь все выкладки теоретические, пусть кто нибуть впихнет код в комментариях если так уж тяжело человеку помочь. Почему перед фактом человек может попросить кармы (темы о кармакредитах етц ...) а постфактум и с плюсовой кармой нет ?
+1
basilisk #
вращать шар — чертовски сложная задача :))
0
foff4ik #
Канечно, когда синусов и косинусов еще не знаеш...
0
foff4ik #
Щас то конечно с улыбкой смотрю на себя тогда, а на тот момент это было типа открытие...
0
Great #
тяжелое детство было +)
+1
bask #
Самое сложное в капчах - это подбор параметров, при которых и человеку будет просто распознать, и машине затруднительно. Иногда на это уходит несколько дней, а то и недель
+1
blockdog #
Тянет на приз зрительских симпатий (:
ЗЫ: Карму плюсанул, но не для выкладывания, а просто из уважения.
+1
fog #
Плюс поставил, но демиург уже давно предложил решение без всяких формул для простых умов.
+3
bO_oblik #
Карму дали, гони капчу пацан.
>_<
+1
globik #
Навеяно комментарием bask'а.

Мне кажется распознать эту каптчу не очень сложно:
1) Сетка уже наложена, картинку переносим в 3D.
2) Символы уже порядочно возвышаются, их можно выделить из основного зашумленного фона
3) Дальше уравниваем поверхность и избавляемся от глубины (оси Z)
4) На этом этапе у нас банальная плоская картинка с символами, которые не составит труда распознать =)
p.s. Не претендую на самый оптимальный алгоритм, просто этот мне кажется наиболее интересным =)


А можно и вовсе с помощью поворота и растягивания каптчи получить что то подобное:
http://img204.imageshack.us/img204/989/capkh4.jpg
Здесь видно что поверхность букв более темная чем фон, фильтруем, и снова получаем плоскую картинку с символами.
0
dab512 #
а давай ка на вот этом ?)
http://i.piccy.kiev.ua/i2/55/b1/5f5bbef6…
0
Sannis #
Чесно говоря, тут всё точно также :)
0
dab512 #
результат в студию :)
0
AirWorker #
Кажется, на Хабре назревает война Капчеписателей и Капчеломателей :)
0
dab512 #
я есличе к ломателям отношусь %)
0
AirWorker #
Умы бродят в поисках применения избыточным вычислительным мощностям ))
0
Sannis #
Не, у меня есть другое применение для них ;)
0
Sannis #
А я ни к тем, ни к другим, так что моё мнение можно пропустить.
Писать распознаватель я не буду, но вот что скажу: даже на глаз видно, что на этой картинке, если усреднить, на месте линий букв будет больше интенсивность. Можно пройтись дифференциальным фильтром и будет вполне хороший силуэт, по крайнем мере он должен распознаться, учитывая что сейчас распознают такое:

, имхо здесь будет очень похожее изображение.
+1
zvirusz #
protected function generateCode()
предлагаю изменить следующим образом:
    protected function generateCode()
{
$chars = self::CHARS;
$cnt = count($chars) - 1;
for($i =0; $i<3; $i++){
$this->text .= $chars[mt_rand(0,$cnt)];
}
}
0
G_Z #
пару строк кода и вот первая 3D картинку
+1
ultragex #
А вообще, если разобраться, нужна ли такая капча? Зачем всё усложнять?

Намучился на рапиде сначала с "кооошечками"... (пока воткнул, в чем фишка - думал свихнусь).. Теперь еще и 3Д...
0
hldr #
неплохой код, в целом)
(модифицировал под php4)
–2
cc00ffee #
Правильно-правильно: не напомнишь - кто ж плюсанёт?
+1
Static #
КлаССный.
+1
kingoleg #
Сколько времени потратил?
0
dinis #
интересно, все скопировали название класса как Capthca3d?
0
gvidon #
автор дьявол:)))
–2
Devgru #

$z += 1.4 * sin(($x+$this->startX)*3.141592654/15)*sin(($y+$this->startY)*3.141592654/15);

не проще ли так:

$z += 1.4 * sin(($x+$this->startX)*M_PI/15)*sin(($y+$this->startY)*M_PI/15);
+1
ecl #
а обязательно вылизыванием кода в комментах заниматься, человек преподнес основную идею, дал исходный код для полета вашей мысли, а тут еще в таких мелочах зад..чивают, впрочем, как всегда...
0
AirWorker #
Просто класс
0
AirWorker #
Возможно один из самых крутых постов в этом блоге
+2
neelts #
Blur + Gamma Correction и капча вполне распонаваема

habr

0
IDDQD #
Не хочу тебя расстраивать, но где-то я подобную капчу видел.
–2
yar #
GPL - не зачетно, самая идиотская лицензия.
Если хочешь добра людям, надо выкладывать под LGPL.
0
yoreeq #
а в чем необходимость
$c = (int) ($this->zFunction($x,$y)*32);
этой строки для задания цвета?
убрав её и заменив следующую на:
$linesColor = imageColorAllocate($this->image, 0, 0, 0);
быстродействие увеличилось почти в два раза, судя по микротайму.

А вообще, большое спасибо :)
0
AlexKolupaev #
Автору - пламенный капчапривет!
0
LDEV #
10x!
0
maserg #
вообще то тема стара...

вот еще от 2006-02-06 http://demiurg.livejournal.com/70914.htm…

исходники http://maxx.e-taller.net/lj/captcha-php.…
0
DEHisOK #
Спасибо!
0
Trave #
опечатка в имени класса
Capthca3d а должно быть Captcha3d

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