Каптча 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 <to.kandy@gmail.com>
    */

    <?php 


    $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
    Поделиться публикацией
    Похожие публикации
    Реклама помогает поддерживать и развивать наши сервисы

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

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

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

                P.S. Пожалуй, без карматоргов Вы бы и так заработали свою двадцатку, а так — сомневаюсь.
                • НЛО прилетело и опубликовало эту надпись здесь
                  • НЛО прилетело и опубликовало эту надпись здесь
                    • НЛО прилетело и опубликовало эту надпись здесь
                      • +3
                        Автор написал: "31 штука в секунду".
                        • НЛО прилетело и опубликовало эту надпись здесь
                    • 0
                      Автор, будьте добры, поделитесь кодом и будет вам счастье! ;)
                      • +5
                        Да ладно вам.. что вам кармы жалко для человека?
                        Он же не за хухры-мыхру просит.. такая работа достойна поощрения.

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

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

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

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

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

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

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

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


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

                                                                                                , имхо здесь будет очень похожее изображение.
                                                                                    • +1
                                                                                      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
                                                                                        пару строк кода и вот первая 3D картинку
                                                                                        • +1
                                                                                          А вообще, если разобраться, нужна ли такая капча? Зачем всё усложнять?

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

                                                                                                        $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
                                                                                                          а обязательно вылизыванием кода в комментах заниматься, человек преподнес основную идею, дал исходный код для полета вашей мысли, а тут еще в таких мелочах зад..чивают, впрочем, как всегда...
                                                                                                        • 0
                                                                                                          Просто класс
                                                                                                          • 0
                                                                                                            Возможно один из самых крутых постов в этом блоге
                                                                                                            • +2
                                                                                                              Blur + Gamma Correction и капча вполне распонаваема

                                                                                                              habr

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

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

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

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

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