=head1 NAME
-perlfaq9 - Networking ($Revision: 7875 $)
+perlfaq9 - Networking ($Revision: 8539 $)
=head1 DESCRIPTION
=head2 How do I check a valid mail address?
-You can't, at least, not in real time. Bummer, eh?
+(partly contributed by Aaron Sherman)
-Without sending mail to the address and seeing whether there's a human
-on the other end to answer you, you cannot determine whether a mail
-address is valid. Even if you apply the mail header standard, you
-can have problems, because there are deliverable addresses that aren't
-RFC-822 (the mail header standard) compliant, and addresses that aren't
-deliverable which are compliant.
-
-You can use the Email::Valid or RFC::RFC822::Address which check
-the format of the address, although they cannot actually tell you
-if it is a deliverable address (i.e. that mail to the address
-will not bounce). Modules like Mail::CheckUser and Mail::EXPN
-try to interact with the domain name system or particular
-mail servers to learn even more, but their methods do not
-work everywhere--especially for security conscious administrators.
-
-Many are tempted to try to eliminate many frequently-invalid
-mail addresses with a simple regex, such as
-C</^[\w.-]+\@(?:[\w-]+\.)+\w+$/>. It's a very bad idea. However,
-this also throws out many valid ones, and says nothing about
-potential deliverability, so it is not suggested. Instead, see
-http://www.cpan.org/authors/Tom_Christiansen/scripts/ckaddr.gz ,
-which actually checks against the full RFC spec (except for nested
-comments), looks for addresses you may not wish to accept mail to
-(say, Bill Clinton or your postmaster), and then makes sure that the
-hostname given can be looked up in the DNS MX records. It's not fast,
-but it works for what it tries to do.
+This isn't as simple a question as it sounds. There are two parts:
-Our best advice for verifying a person's mail address is to have them
-enter their address twice, just as you normally do to change a password.
-This usually weeds out typos. If both versions match, send
-mail to that address with a personal message that looks somewhat like:
+a) How do I verify that an email address is correctly formatted?
- Dear someuser@host.com,
+b) How do I verify that an email address targets a valid recipient?
- Please confirm the mail address you gave us Wed May 6 09:38:41
- MDT 1998 by replying to this message. Include the string
- "Rumpelstiltskin" in that reply, but spelled in reverse; that is,
- start with "Nik...". Once this is done, your confirmed address will
- be entered into our records.
+Without sending mail to the address and seeing whether there's a human
+on the other end to answer you, you cannot fully answer part I<b>, but
+either the C<Email::Valid> or the C<RFC::RFC822::Address> module will do
+both part I<a> and part I<b> as far as you can in real-time.
+
+If you want to just check part I<a> to see that the address is valid
+according to the mail header standard with a simple regular expression,
+you can have problems, because there are deliverable addresses that
+aren't RFC-2822 (the latest mail header standard) compliant, and
+addresses that aren't deliverable which, are compliant. However, the
+following will match valid RFC-2822 addresses that do not have comments,
+folding whitespace, or any other obsolete or non-essential elements.
+This I<just> matches the address itself:
+
+ my $atom = qr{[a-zA-Z0-9_!#\$\%&'*+/=?\^`{}~|\-]+};
+ my $dot_atom = qr{$atom(?:\.$atom)*};
+ my $quoted = qr{"(?:\\[^\r\n]|[^\\"])*"};
+ my $local = qr{(?:$dot_atom|$quoted)};
+ my $domain_lit = qr{\[(?:\\\S|[\x21-\x5a\x5e-\x7e])*\]};
+ my $domain = qr{(?:$dot_atom|$domain_lit)};
+ my $addr_spec = qr{$local\@$domain};
+
+Just match an address against C</^${addr_spec}$/> to see if it follows
+the RFC2822 specification. However, because it is impossible to be
+sure that such a correctly formed address is actually the correct way
+to reach a particular person or even has a mailbox associated with it,
+you must be very careful about how you use this.
-If you get the message back and they've followed your directions,
-you can be reasonably assured that it's real.
+Our best advice for verifying a person's mail address is to have them
+enter their address twice, just as you normally do to change a
+password. This usually weeds out typos. If both versions match, send
+mail to that address with a personal message. If you get the message
+back and they've followed your directions, you can be reasonably
+assured that it's real.
A related strategy that's less open to forgery is to give them a PIN
(personal ID number). Record the address and PIN (best that it be a
-random one) for later processing. In the mail you send, ask them to
+random one) for later processing. In the mail you send, ask them to
include the PIN in their reply. But if it bounces, or the message is
included via a "vacation" script, it'll be there anyway. So it's
best to ask them to mail back a slight alteration of the PIN, such as
=head1 REVISION
-Revision: $Revision: 7875 $
+Revision: $Revision: 8539 $
-Date: $Date: 2006-10-04 22:39:26 +0200 (mer, 04 oct 2006) $
+Date: $Date: 2007-01-11 00:07:14 +0100 (Thu, 11 Jan 2007) $
See L<perlfaq> for source control details and availability.
=head1 AUTHOR AND COPYRIGHT
-Copyright (c) 1997-2006 Tom Christiansen, Nathan Torkington, and
+Copyright (c) 1997-2007 Tom Christiansen, Nathan Torkington, and
other authors as noted. All rights reserved.
This documentation is free; you can redistribute it and/or modify it