Иногда программисту приходится сталкиваться с определенными ситуациями, которые сводятся к приему какой-либо информации. Она может носить как верный, так и неверный характер. Яркий пример такого случая - запрос E-mail адреса со стороны клиента. Требуется наиболее точно определить достоверность этого адреса. Что примечательно, решения у этой задачи нет, так как проверить E-mail адрес на 100% точность невозможно. Сам "синтаксис" адреса может быть правильным, но адреса может не существовать
в принципе.

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

Самое простое - проверка синтаксиса E-mail адреса. По сути, адрес представляет собой три части: имя пользователя, имя хоста и домен. Требования к этим частям следующие: имя юзера не должно содержать спецсимволов, ровно как и весь адрес. Юзер и хост, хост и домен должны быть разделены собакой и точкой соответственно.

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

#!/usr/bin/perl

## Проверка E-mail адреса на правильность

#!/usr/bin/perl
chomp($email=); ##
Запросим адрес из командной строки.
if ($email=~/(\w+)\@(\w+)\.(\w+)/) {
print "E-mail верный\n"
} else {
print "E-mail неверный\n"
}
exit;

Все это работает, даже при такой банальной проверке. Но, еще раз скажу, проверка синтаксиса это только начало. Основная проверка должна показать истинность или ложь E-mail адреса, основываясь на показания сервера. Эти показания могут быть получены с smtpd, причем если доступна команда vrfy, которая показывает, есть ли данный E-mail в системе. Как ты понимаешь, использование vrfy небезопасно, поэтому большинство админов делают эту команду недоступной. Но тем не менее, я расскажу как проверить адрес используя 25 порт.

Для осуществления задуманного, нам необходимо наличие модуля Net::DNS, который достанет MX для заданного хоста. Затем, осуществим соединение с MX-сервером и получим данные (если таковые имеются). Если команда отключена - просто завершим работу скрипта.

Итак, собственно код:

#!/usr/bin/perl

use strict;
use IO::Socket;
use Sys::Hostname; ##
Заюзаем модуль определения хоста и сокеты

my $mx=0;
eval {
require Net::DNS; ##
подгрузим модуль DNS
Net::DNS->import("mx");
$mx=1;
}

foreach $addr (@ARGV) {
($name,$host)=split(/\@/,$addr); ##
Пропарсим командную строку на наличие адресов для проверки
my @hostnames;
@hosts = map {$_->exchange } mx($host) if $mx; ##
Если модуль DNS был подгружен - узнаем MX
@hosts=($host) unless @hosts; ##
Иначе подразумеваем, что MX и есть хост

foreach $host (@hosts) {
$sock=IO::Socket::INET->new("$host:25"); ##
Создаем соединение для каждого хоста

$sock->autoflush(1); ## Вырубим буферайз

print $sock "HELO ".hostname()."\015\012";
print $sock "VRFY $host\015\012";
print $sock "QUIT\015\012"; ##
Проверим адрес VRFY
while($sock) {
/^220\b/ && next; ##
Если все ок - выведем данные
/^221\b/ && last; ##
Иначе - использование VRFY невозможно
s/250\b[\-\s]+//;
print;
}
close($sock); ##
Закроем сокет
}

Таким образом можно добиться проверки адреса на валидность, уже подтвержденную сервером. Тебе осталось лишь корректно обработать данные, которые скажет сервер и делать выводы о правильности мыльника.

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

Оставить мнение