Ошибка: Failed to parse the Currency Converter XML document.
$1 603.45


Ошибка: Failed to parse the Currency Converter XML document.
$1 473.94


Ошибка: Failed to parse the Currency Converter XML document.
$1 763.68


Проверка e-mail адреса на существование

Я уже много раз слышал вопрос: «Как проверить e-mail на существование?». Видел на них много ответов, но во всех было сказано, что проверить никак нельзя, предлагались только обходные пути, такие как отправка письма для подтверждения. Однако, я попытаюсь решить эту проблему.

Для проверки на существование будем делать следующее:
Проверка на синтаксическую верность адреса
Проверка существования почтового домена в DNS
Проверка на доступность сервера
Проверка существования аккаунта на сервере

Да, мой вариант решения тоже не идеален и стопроцентной гарантии не даёт, но все же даёт хороший результат!

Начнём с того, что в первой половине e-mail адреса могут присутствовать только цифры, латинские буквы, точка, тире и знак подчёркивания, прицем начианться адрес должен с буквы. В домене могут быть только цифры, латинские буквы, тире и точки. Проверить на соответствие такому формату в перле можно следующим образом:
$email = «email@address.com»;

    
    if($email =~ /^[a-zA-Z_\.-][a-zA-Z0-9_\.-\d]*\@[a-zA-Z\.-\d]+\.[a-zA-Z]{2,4}$/)

    
    {

    
     # действия, выполняемые если e-mail верный


    
    }else{

    
           # действия, выполняемые если e-mail НЕверный

    
         }

    
    
Это была самая простая часть, теперь же, попробуем узнать, существует ли почтовый домен или нет?
Для этого нам понадобится немного кофе, сигареты и библиотека Net::DNS.

Для чего нужны первые два компонента и как ими пользоваться, вы, я думаю, знаете, меня же больше интересует третий компонент. Если кто не знает для чего нужен DNS, кратко оъясняю... Если ваш почтовый адрес my-name@my-e-mail-server.com, то это вовсе не значит, что почта, отправляемая на этот адрес будет получена сервером my-e-mail-server.com. Для того чтобы узнать, какой сервер должен получить эту почту существуют DNS сервера, в которых хранятся MX (Mail eXchange) записи. Для того чтобы получить их от сервера и нужна библиотека Net::DNS. Вот как это делается:
#!/usr/bin/perl

    
    use Net::DNS;

    
    

    
    $email = «email@address.com»;

    
    $dns = «212.164.166.11»;        # DNS Сервер

    
    

    
    $res = new Net::DNS::Resolver;

    
    $res->nameservers($dns);

    
    

    
    print «Content-type: text/html; charset=[b]windows[/b] — 1251\n\n»;

    
    

    
    $email =~ /.*\@(.*)$/;

    
    $domain = ;

    
    

    
    my @mx = mx($res, $domain);

    
    if(@mx)

    
    {

    
     my $rr = shift(@mx);

    
     my $mxserver = $rr->exchange;

    
     print «Сервер для $email: $domain»;

    
    }else{

    
          print «Не удалось определить сервер для $email»;

    
         }

    
    
Этот небольшой скрипт попытается определить сервер для почтового адреса. Ну вот, теперь, если кто-то ввёл от балды e-mail вида asd@fgh.jkl, то скрипт может отреагировать на это, например, попросить ввести правильный e-mail. Но такая проверка не даёт 100 процентной гарантии того, что e-mail юудет введён верно, так как домен для адреса no-such-account@mail.ru будет найден, но такого аккаунта на почтовом сервере не существует.

Что же делать? Можно попробывать подключиться к серверу и проверить, примет ли он такой адрес. Заодно объеденим скрипт с предыдущими проверками.
#!/usr/bin/perl

    
    use Net::DNS;

    
    use IO::Socket;

    
    use CGI::Carp qw(fatalsToBrowser);

    
    

    
    my $email = «my@mail.ru»;

    
    my $emailfrom = «email@address.com»;

    
    

    
    print «Content-type: text/html; charset=[b]windows[/b] — 1251\n\n»;

    
    

    
    ############################################################

    
    

    
    if($email !~ /^[a-zA-Z_\.-][a-zA-Z0-9_\.-\d]*\@[a-zA-Z\.-\d]+\.[a-zA-Z]{2,4}$/)

    
    {

    
     print «e-mail неправильного формата!

    \n»;

    
     exit;

    
    }

    
    

    
    ############################################################

    
    

    
    my $dns = «212.164.166.11»;        # DNS Сервер

    
    

    
    my $res = new Net::DNS::Resolver;

    
    $res->nameservers($dns);

    
    

    
    $email =~ /.*\@(.*)$/;

    
    my $domain = ;

    
    

    
    my @mx = mx($res, $domain);

    
    if (!@mx) {

    
    print «Сервер для домена $domain не обнаружен!

    \n»;

    
    exit;

    
    }

    
    

    
    my $rr = shift(@mx);

    
    my $mxserver = $rr->exchange;

    
    

    
    ############################################################

    
    

    
    my $handle = IO::Socket::INET->new(

    
    Proto  => «tcp»,

    
    PeerAddr  => $mxserver,

    
    PeerPort  => 25);

    
    

    
    if ($handle) {

    
    $handle->autoflush(1);

    
    print $handle «HELO $mxserver\n»;

    
    print $handle «MAIL FROM: $emailfrom\n»;

    
    my $stype = 0;

    
    my $regged = 0;

    
    my $isvalid = 1;

    
    $email =~ /^([a-z$ch2]+)\@([a-z$ch]+\.[a-z]{2,4})$/;

    
    my ($em,$eh) = (,);

    
    if ($stype) {

    
    print $handle «RCPT TO: $email\n»;

    
    }

    
    else {

    
    print $handle «VRFY $em\n»;

    
    }

    
    cycle:

    
    my $rd =;

    
    chomp($rd);

    
    # Hello From Server

    
    if ($rd =~ /^220/) {goto cycle;}

    
    

    
    # HELO Reply

    
    elsif ($rd =~ /^250 \S+ hello/i) {goto cycle;}

    
    

    
    # MAIL FROM Reply

    
    elsif ($rd =~ /^250/i && !$regged) {$regged = 1;goto cycle;}

    
    

    
    # Unknown command «VRFY *»

    
    # VRFY not available

    
    elsif (($rd =~ /^252/ || $rd =~ /^550 5\.5\.2/ || $rd =~ /^502/) && !$stype)

    
    {

    
     $stype = 1;print $handle «RCPT TO: $email\n»; goto cycle;

    
    }

    
    

    
    # 250
    
    
verified

        
        # 250

    
    
, Recipient ok

        
        # 250 ok

        
        # 250 2.1.5 *

        
        # В принципе, можно, да и правильне будет просто 250 *, но при таком

        
        #
        
        корявом написании скрипта так будет надежней

        
        elsif($rd =~ /^250  verified/i ||

        
              $rd =~ /^250 ,? recipient ok/i ||

        
              $rd =~ /^250 ok/i ||

        
              $rd =~ /^250 2\.1\.5/i) {

        
        print «$email верный.

        \n»;

        
        }

        
        

        
        # 550 5.7.1
         user unknown

        
            elsif($rd =~ /^550/)

        
            {

        
             print «$email неверный.

        \n»;

        
             $isvalid = 0;

        
            }

        
            

        
            if ($isvalid) {

        
            # Отправляем почту... (как это сделать читай ниже)

        
            }

        
            close $handle;

        
            if (!$isvalid) {exit;}

        
            }

        
            else {

        
            print «Не удалось подулкчиться к серверу!

        \n»;

        
            exit;

        
            }

        
            # Теперь делаем что угодно...

Этот способ позволит при помощи сервера узнать, существует ли такой e-mail или нет. Хотя не все сервера сообщают об этом, но теперь, по крайне мере в большинстве случаев вы сможете определить что e-mail неверный.

Вообще, проверка на валидность может понадобиться вам при регистрации пользователей в вашей системе. Если необходимо после регистрации отправить письмо на зарегестрированыый адрес, то это можно сделать сразу же после проверки. Это значительно сократит время работы скрипта. Для того чтобы отправить почту вам будет необходимо вставить в скрипт следующие строки:
    if (!$stype) {

    
    print $handle «RCPT TO: $email\n»;

    
    }

    
    print $handle «DATA\n»;

    
    # Выводим заголовки

    
    print $handle «From: \n»;

    
    print $handle «To: \n»;

    
    print $handle «Subject: Test letter\n\n»;

    
    # Печатаем текст письма

    
    print $handle «Hello! It is test!\n»;

    
    # Одиночная точка — знак того что письмо закончилось

    
    print $handle «.\n»;
Вот в принципе и всё! Удачи!

 

Интересное

Четыре правила...
Правило первое Научить дизайну, вот так, путем написания нескольких заметок, нельзя. Если по HTML-верстке или азам проектирования веб-сайта еще можно написать пошаговую инструкцию, то с дизайном...
Подробнее...
Советы по графике в Delphi
Вы наверное часто видели довольно хитроумные картины, на которых непонятно что изображено, но все равно необычность их форм завораживает и приковывает внимание. Как правило, это хитроумные формы...
Подробнее...
Захват чужих имен
Особенности доменных имен, уже бывших в чей-то собственностиНе знаю, как вам, но мне иногда кажется, что все лучшие доменные имена уже разобрали. Не раз я придумывал потрясающее доменное имя, и...
Подробнее...
Что такое torrent? Что...
Что такое bittorrent?Bittorrent — это программа, которая позволяет очень быстро распространять файлы (обьемные файлы) среди пользователей. То есть, это не пиринговая сеть в чистом виде, а скорее...
Подробнее...
GSM – шлюз: Как через...
У меня возникла необходимость по нескольку раз в день принимать и отправлять фак- сы на даче, где нет городского телефона. Слышал, что для таких целей можно каким-то образом приспособить мобильный...
Подробнее...
Уменьшаем траффик вдвое
Заставила меня написать эту статью интересная возможность. Это возможность пользоваться сетью, используя любую технологию, в которой оплата взимается по траффику(например, ADSL или GPRS), снижая...
Подробнее...
Firefox: Настройка RSS
Много слышал об RSS и даже несколько раз пытался пользоваться специальными программами для чтения. Но устанавливать дополнительное ПО не хочется, тем более что в Firefox есть встроенный клиент...
Подробнее...
Использование сессий в PHP
Очень часто при написании скриптов на php необходимо хранить некоторую информацию о посетителе в течение всего сеанса его работы. Типичным примером такой ситуации является необходимость...
Подробнее...
Типизированные файлы
Типизированный файл — это файл в котором записанны идентичные структуры. Например любой файл можно считать файлом байтов — т.е. можно его читать байт за байтом, можно перейти сразу к любому...
Подробнее...
Режим редактирования в IE
Оказывается ie может редактировать открытые им документы, и не только текст, но и в том числе вставлять имиджи и т.п. По сути дела полноценный html-editor у нас в руках, но только об этом...
Подробнее...