Ещё о защите e-mail адресов на веб-страницах

Оригинальная защита e-mail адресов от сканирования спам-роботами. Мы не будем кодировать адреса, мы будем их… рисовать!

Озащите e-mail адресов от сканирования спам-роботами в Интернетеписалось немало. Скорее наоборот, очень много. Однако все способысводятся в основном к одному – кодирование адресов таким образом, чтобыспам-роботы не смогли его распознать, а для человека это не составилобы труда. Чаще всего мне встречались такие варианты: name[at]server.ru,name(a)server.ru и даже name(Shift+2)server.ru. Вариант, конечно, тожехороший, но спам-роботы быстро учатся. Опытный интернетчикдогадается, что [at] нужно заменить на @, но некоторые люди копируютадрес name[at]server.ru прямо в почтовую программу, а потом удивляются– почему письма не доходят 🙂 Вначале проблема спама не так беспокоиламеня, пока однажды горы рекламных писем не посыпались на мой ящик. Вэтот же день нашёл простой выход: собачку можно показывать каккартинку, всё остальное – как символы. Внешне – обычный e-mail, аскопировать не получится.

Предлагаю вашему вниманию простой идоступный способ публикации e-mail адресов без опасения, что егопросканирует спам-робот. Хотя, возможно, и просканирует, но для этогоон должен обладать искусственным интеллектом 🙂 Требования: наличие PHPс библиотекой GD. Многие наверно догадались, что мы будем делать садресами. Мы будем их… рисовать! Назовём наш скрипт email. php.Алгоритм достаточно прост:
Одним из способов скрипт получает на вход е-mail адрес:
Получим адрес автора из базы данных, указав например id статьи или записи в гостевой книге (каталоге файлов, ссылок и т.д.).
Передадимадрес скрипту в явном виде: email. php? adr= name@ server. ru (но эточревато тем, что e-mail всё-таки засвечен). Такая защита равносильнаеё отсутсвию.
Передадим адрес скрипту в неявном виде: email. php? name= name& server= server. ru
Передадимадрес скрипту в зашифрованном виде: email. php? adr=anzr@freire.eh(воспользовавшись функцией str_rot13 () , которая смещает коды всехлатинских букв вверх на 13).
Скрипт расшифровывает данные, генерирует картинку с изображением адреса и возвращает её браузеру.

Для начала рассмотрим процесс рисования, так как он впоследствии останется неизменным:
$size = 2; $im = imagecreate(imagefontwidth($size)*strlen($adr), imagefontheight($size));

Здесьнет ничего особенного. Исходные данные: $ adr – адрес, который надонарисовать, $size – размер шрифта на картинке (легко подбирается поразмеру и жирности, внешне похож на Tahoma, Verdana, Arial). Функцияimagecreate() создаёт картинку и помещает указатель на неё в переменную$im. Однако для этого вычислим размеры будущей картинки, исходя изразмера шрифта и количества символов в строке.

imagefontwidth($size)– определяет ширину одного символа при размере $size. Умножим её надлину строки strlen($adr) и получим ширину будущей картинки. Высотакартинки вычисляется функцией imagefontheight($size). Добавляем впалитру изображения цвета фона и надписи (соответственно белый икрасный)
$bg = imagecolorallocate($im, 255, 255, 255); $black = imagecolorallocate($im, 0x00, 0x00, 0x00);

Если цвет фона вашего сайта не белый, сделаем так:
imagecolortransparent($im,$bg);

Цвет$ bg в палитре станет прозрачным, поэтому $ bg может быть любым цветом.Цвет символов задаётся в соответствии с вашими потребностями.

Делаем надпись:
imagestring($im, $size, 0, 0, $adr, $black);

И выводим картинку :
header(Content-type: image/png); imagepng($im);

Теперьрассмотрим, какими способами можно получить e-mail для обработки. Втаблице помещены варианты адресации и соответствующие фрагменты кода.
Извлечение e-mail из базы данных MySQL.

email.php?id=1     mysql_connect(localhost, username, password);mysql_select_db(database); $id = abs(intval($id)); $query = SELECTemail FROM table WHERE table_id=$id; $result = mysql_query ($query);$f = mysql_fetch_array($result); if (empty($f[email])) $adr =n/a;  else $adr = $f[email];

Прямая передача адреса

email. php? adr= name@ server. ru     
дополнительный код не нужен

Раздельная передача адреса

email.php?name=name&
server=server.ru      $adr = $name.”@”.$server

Передача закодированного адреса

email. php? adr=anzr@freire.eh    
(адресбыл закодирован функцией str_ rot13(), она же раскодирует его, потомучто букв в латинском алфавите всего 26, а смещение каждый раз на 13)
$adr = str_rot13($adr);

Вот весь скрипт целиком (добавьте нужный вам способ получения адреса):

Вывод картинки вместо реального e-mail делается примерно так:
Ваш e-mail: name@server.ru
Ваш e-mail:

Теперь,когда мы знаем, как заменять e-mail адреса, можно написать функцию,которая будет производить такие замены в заданном тексте при помощирегулярных выражений. Это может потребоваться при тотальной фильтрациивсего вывода, пакетной обработке HTML-файлов, выводе информации из БД.

Разделим адрес на 3 части:
(Имя)@(Домен).(Зона)

И того уже имеем паттерн типа:
(.*)@(.*).(.*)

Подэту формулу подойдут миллиарды выражений, но мы идём дальше поспецификации e-mail адреса. Имя пользователя должно состоять из a-z,A-Z, 0-9, а также ., _ и -. Если не ошибаюсь, строгих правилпо этому поводу никогда не было, где-то разрешены и другие символы, этооснова. A-Z добавлено на случай если пользователь любит прописыватьсвоё мыло покруче. Длина имени от 2-х до 256-ти символов (см. RFC).Дальше домен, тоже самое – a-z, A-Z, 0-9, ., – и всё! Длинадоменного имени та же, единственная загвоздка – если мыло находится нев домене второго уровня, а, скажем, третьего или даже четвёртого. Тутснова в RFC кидаться надо, поскольку и сама служба DNS не лишенаответа типа HTTP 414 :). Длина домена не может превышать 256символов, но вот входят ли в это число поддомены – не помню. Зона –здесь просто a-z, A-Z от 2-х до 4-х символов.

В итоге получается что-то такое:
([a-zA-Z0-9 -> . -> – -> _]{2,256})@(([a-zA-Z0-9 -> . -> -]{2,256}).([a-z]{2,4}))

Можнопроверить, не начинаются ли (или заканчиваются) подвыражения \\1, \\2символами типа . или -, дальше – на что фантазии хватает. Используявычисленное регулярное выражение (невольно вспоминаются лекции поматанализу), напишем функцию, которая будет заменять все адреса e-mailв строке на тэг IMG и возвращать изменённую строку. В качестве функциизамены я использовал preg_replace() с синтаксисом Perl RegExp.

email_ replace. php
<?php// функция замены e-mail адресов function email_replace($text) { $exp =/([a-zA-Z0-9 -> . -> – -> _]{2,256})@(([a-zA-Z0-9 -> . -> -]{2,256}).([a-z]{2,4}))/;returnpreg_replace($exp, , $text); } // исходная строка со множествомe-mail адресов$text =<<; echo email_replace($text); //изменённая строка?>