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

Задачи again, Chat OCR, concept 3G и AOL device, 1000

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

Решение четыре

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

Олег Лычаный, Макс Козлов и Дмитрий Мараков, независимо друг от друга, прислали мне четвертое решение задачи о садовнике. Решая эту задачу я, например, как-то автоматически принял предпосылку, что все расстояния между соседними рядами равны, хотя в условии задачи этого нигде не утверждается.

Если принять, что ряды располагаются как угодно, то могут появится такие красивые решения, как звезда. Может кто-нибудь перебиралку напишет? Мне лениво. :)

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

В последнее время появилась мода на регистрацию при помощи «магических чисел» нанесенных на картинку. Если вы не знаете о чем речь, попробуйте, например, зарегистрировать e-mail на Chat.RU. Идея проста — на картинку наносится число, которое человек при регистрации должен «вбить» в текстовую форму, считается, что человеку это особых неудобств не приносит, а вот регистрационные скрипты с этим ничего сделать не могут.

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

Тот же Chat.RU, для примера, каждые несколько часов генерирует набор пятизначных цифр, хеширует их через MD5 и помещает все соответствия в базу данных. Этот хеш является параметром для скрипта, генерирующего картинку.

Способ достаточно странный и трудоемкий, но «кул хацкеров» все же отпугивает. Странный потому что совершенно непонятно для чего оставлять хоть какое-то, пусть непрямое, соответствие между номером на картинке и параметром используемым для его генерации — перебор на Perl с восстановлением числа на Pentium III-866 занимает, в среднем, примерно 30 секунд. Если не повезет — все 70. Я пробовал.

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

Картинка в ASCII

Забегая вперед, скажу, что концентрироваться пришлось недолго. Сначала я обратил внимания на то, что выдаваемая пользователю картинка имеет формат PNG, значит новая GD-библиотека, вкомпиленная в PHP на моей машине, вполне сможет с ней работать. Поэтому первое что я сделал — прошелся по всей картинке и, двумя циклами, перевел ее в ASCII — графику, чтобы лучше рассмотреть, а заодно убедиться, что GD картинку «понимает».

Моя задача очень упростилась — как оказалось все цифры в строке одинакового размера, а координаты начала печати от картинки к картинке не изменяются ни на пиксел.

Сверять цифры с заранее заготовленными образцами было слишком просто и грустно, так что я решил просто суммировать количество пикселей, составляющих цифру, в каждом столбце одного знака и сравнивать получившееся значение с просчитанным заранее. Как оказалось для этой задачи необходимы только первые три столбца каждой цифры. Получилась такая вот программка на PHP, которая позволяет регистрировать e-mailы на Chat.RU в любом количестве.

function OCRNum($URL)
{
        $out = '';
        $nums = array (464,23,245,242,233,674,685,343,377,266);
        $png = imagecreatefrompng ($URL);

        for ($x = 10; $x<54; $x++)
        {
                $sums = array(0,0,0);

                for ($i = 0; $i<3; $i++)
                for ($y = 10; $y<20; $y++)
                $sums[$i]+= imagecolorat ($png, $x+$i,$y);

                $x+=8;
                $out.= array_search((int)join('',$sums), $nums);
        };

        return $out;
};

function GetCryptKey()
{
        $fp = fopen ("http://chat.ru/user/register.html?", 'r');
        while (!feof ($fp))
        {
                $line = strstr($line = fgets($fp, 1024), 'personal_key_crypt=');
                if ($line!==false) break;
        };
        fclose ($fp);

        if (ereg ("[[:alnum:]_]+=([^\">]+)", $line, $regs))
        return $regs[1]; else return false;
};

function RegProc($crypt_key)
{
        global $user, $pass;

        $key = OCRNum("http://chat.ru/user/image_gen.html?".
        "personal_key_crypt=$crypt_key");

        $URL = "http://chat.ru/user/register.html?personal_key=$key&".
        "personal_key_crypt=$crypt_key&username=$user&pw1=$pass&pw2=$pass&".
        "action=Register/Зарегистрировать";

        $fp = fopen ($URL, 'r');
        while (!feof($fp))
        {
                $line = fgets ($fp, 2048);
                if (strstr ($line, '<head>'))
                echo "$line\n<BASE HREF=http://www.chat.ru>\n"; else
                echo $line;
        };
        fclose ($fp);
};

if ($user=='' || $pass=='')
echo <<<HTML
<STYLE>
        body, td, input {font-family: Trebuchet MS; font-size: 15px}
</STYLE>
<BODY BGCOLOR=WHITE TEXT=BLACK>
<TABLE WIDTH=300>
<FORM ACTION=$PHP_SELF>
<TR><TD>User name:</TD><TD><INPUT TYPE=TEXT NAME=user></TD></TR>
<TR><TD>Password:</TD><TD><INPUT TYPE=TEXT NAME=pass></TD></TR>
<TR ALIGN=CENTER><TD COLSPAN=2><INPUT TYPE=SUBMIT VALUE=Register>
</TD></TR>
</TABLE>
</FORM>
HTML;
else
{
        $ckey = GetCryptKey();
        if ($ckey === false) echo 'Не могу зарегистрировать.'; else
        RegProc ($ckey);
};

Берите, пользуйтесь, пока ребята из Chat.RU не сменили алгоритм. :) Вообще Chat.RU — сервис довольно странный и дырявый, но об этом как-нибудь в другой раз.

Никому игрушечная ведьма в подарок ребенку или младшему брату на Хелоуин (надеюсь, правильно написал) за умеренные деньги не нужна? :) 15 сантиметров в высоту, подвижные конечности и голова, змеи неожиданно появляющиеся из глаз и рта. В комплекте накидка, свеча, две корзины и прочая атрибутика. Очаровашка. [ Вот тут ].

Concept

О «concept car» слышали, пожалуй, все. А вот о концепт-3G-терминалах я, например, слышу впервые. На фотографии справа, например, Nokia 3G Terminal Concept III.

Посмотреть на это все можно вот здесь, а где и когда можно будет купить, надо ли покупать и сколько будет стоить я не знаю. Ибо это всего лишь concept.

Надеюсь, что в след за концептуальными 3G-терминалами появятся и концепт-телефоны, плавно переходящие в массовое производство, а за ними и прочие устройства. Купить мобильник или PDA с таким дизайном я бы не отказался.

AOL device

Не секрет, что кроме всем известной «Аськи» на свете существует великое множество разнообразных интернет-пейджеров. Различных Миранд, Одиго, Триллиантов, Интстант Мессенжеров, Яху пейджеров и прочая и прочая.

До такого, кроме, AOL не додумалась, по-моему, еще ни одна компания. AOL (а точнее одна из хардварных компаний для AOL) объединила обычный пейджер с интернет-педжером и получила устройство, позволяющее получать почту и сообщения AOL IM на такую вот небольшую коробочку с клавиатурой и колесом прокрутки.

Внутри, как не странно, 386-й процессор от фирмы Intel, 4 МБ Flash, 512 КБ SRAM и одна NiMH батарейка AA форм-фактора. Хоть Linux инсталлируй. Размерами этот девайс примерно 63,5×88,9×23,6 мм. Т. е. даже меньше, хотя и толще, чем мой Casio PV-S450.

Продается в штатах по цене в 100$, плюс 30 баксов ежемесячно, за подключение. Очень неплохой бизнес.

Мне кажется оформление мусорных баков у нас в Казани скоро станет одним из видов искусства. Я уже как-то упоминал о «мусоре Эльдорадо», а вот какой перл я увидел на улице Зорге, возле магазина «1000 мелочей».

1000 мелочей

На этом позвольте попрощаться. Пишите! Вашим письмам я радуюсь, как ребенок. С уважением, Евгений Степанищев.