Оригинальная защита 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 может быть любым цветом.
Цвет символов задаётся в соответствии с вашими потребностями.
И выводим картинку : header('Content-type: image/png'); imagepng($im);
Теперь
рассмотрим, какими способами можно получить e-mail для обработки. В
таблице помещены варианты адресации и соответствующие фрагменты кода. Извлечение e-mail из базы данных MySQL.
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.