ईमेल सत्यापन


10

RFC 5321 ( 5322 में कुछ व्याकरण के नियम ) में छूट के साथ एक ई-मेल पते को मान्य करने के लिए एक फ़ंक्शन या प्रोग्राम लिखें, इस छूट के साथ कि आप टिप्पणियों और तह व्हाट्सएप ( CFWS) और सामान्यीकृत पता शाब्दिकों को अनदेखा कर सकते हैं । यह व्याकरण देता है

Mailbox              = Local-part "@" ( Domain / address-literal )

Local-part           = Dot-string / Quoted-string
Dot-string           = Atom *("."  Atom)
Atom                 = 1*atext
atext                = ALPHA / DIGIT /    ; Printable US-ASCII
                       "!" / "#" /        ;  characters not including
                       "$" / "%" /        ;  specials.  Used for atoms.
                       "&" / "'" /
                       "*" / "+" /
                       "-" / "/" /
                       "=" / "?" /
                       "^" / "_" /
                       "`" / "{" /
                       "|" / "}" /
                       "~"
Quoted-string        = DQUOTE *QcontentSMTP DQUOTE
QcontentSMTP         = qtextSMTP / quoted-pairSMTP
qtextSMTP            = %d32-33 / %d35-91 / %d93-126
quoted-pairSMTP      = %d92 %d32-126

Domain               = sub-domain *("." sub-domain)
sub-domain           = Let-dig [Ldh-str]
Let-dig              = ALPHA / DIGIT
Ldh-str              = *( ALPHA / DIGIT / "-" ) Let-dig

address-literal      = "[" ( IPv4-address-literal / IPv6-address-literal ) "]"
IPv4-address-literal = Snum 3("."  Snum)
IPv6-address-literal = "IPv6:" IPv6-addr
Snum                 = 1*3DIGIT
                       ; representing a decimal integer value in the range 0 through 255

नोट: मैंने इसकी परिभाषा को छोड़ दिया है IPv6-addrक्योंकि यह विशेष RFC गलत है और उदा ::1। सही युक्ति RFC 2373 में है

प्रतिबंध

आप किसी भी मौजूदा ई-मेल सत्यापन लाइब्रेरी कॉल का उपयोग नहीं कर सकते हैं। हालाँकि, आप आईपी पते की जाँच करने के लिए मौजूदा नेटवर्क पुस्तकालयों का उपयोग कर सकते हैं।

यदि आप एक फ़ंक्शन / विधि / ऑपरेटर / समतुल्य लिखते हैं, तो उसे एक स्ट्रिंग लेनी चाहिए और अपनी भाषा के लिए एक बूलियन या सत्य / मिथ्या मूल्य वापस करना चाहिए। यदि आप एक प्रोग्राम लिखते हैं, तो उसे स्टड से एक ही लाइन लेनी चाहिए और निकास कोड के माध्यम से वैध या अमान्य इंगित करना चाहिए।

परीक्षण के मामलों

निम्नलिखित परीक्षण मामलों को कॉम्पैक्टनेस के लिए ब्लॉकों में सूचीबद्ध किया गया है। पहले ब्लॉक ऐसे मामले हैं जो पास होने चाहिए:

email@domain.com
e@domain.com
firstname.lastname@domain.com
email@subdomain.domain.com
firstname+lastname@domain.com
email@123.123.123.123
email@[123.123.123.123]
"email"@domain.com
1234567890@domain.com
email@domain-one.com
_______@domain.com
email@domain.name
email@domain.co.jp
firstname-lastname@domain.com
""@domain.com
"e"@domain.com
"\@"@domain.com
email@domain
"Abc\@def"@example.com
"Fred Bloggs"@example.com
"Joe\\Blow"@example.com
"Abc@def"@example.com
customer/department=shipping@example.com
$A12345@example.com
!def!xyz%abc@example.com
_somename@example.com
_somename@[IPv6:::1]
fred+bloggs@abc.museum
email@d.com
?????@domain.com

निम्नलिखित परीक्षण मामले पास नहीं होने चाहिए:

plainaddress
#@%^%#$@#$@#.com
@domain.com
Joe Smith <email@domain.com>
email.domain.com
email@domain@domain.com
.email@domain.com
email.@domain.com
email.email.@domain.com
email..email@domain.com
email@domain.com (Joe Smith)
email@-domain.com
email@domain..com
email@[IPv6:127.0.0.1]
email@[127.0.0]
email@[.127.0.0.1]
email@[127.0.0.1.]
email@IPv6:::1]
_somename@domain.com]
email@[256.123.123.123]

चूंकि IPv6-addrअपरिभाषित छोड़ दिया गया है, और ऐसे परीक्षण मामले हैं जिनके पास आईपीवी 6 पते हैं, क्या उन्हें सत्यापित करने का एक सही तरीका है?
arnnew

क्यों चाहिए email@d.comऔर ?????@domain.comअसफल?
GRC

1
@ardnew, मैंने संबंधित RFC के लिए एक लिंक जोड़ा है। मैं इसे इनलाइन नहीं करना चाहता क्योंकि यह प्रश्न पहले ही काफी लंबा है।
पीटर टेलर

@grc, अच्छा सवाल। मैंने उन्हें जाँच लिया है, क्योंकि किसी ने भी कई महीनों के दौरान यह सवाल नहीं उठाया कि प्रश्न सैंडबॉक्स में था , लेकिन मैं यह नहीं देख सकता कि वे क्यों असफल हो जाएं, इसलिए मैंने उन्हें "पास" पक्ष में स्थानांतरित कर दिया है।
पीटर टेलर

क्या लंबाई सीमा भी आवश्यक है? पूरे ईमेल पते के लिए 254 / स्थानीय-भाग के लिए 64 / प्रत्येक डोमेन लेबल के लिए 63?
माइकलरटन ने

जवाबों:


2

पायथन 3.3, 261

import re,ipaddress
try:v,p=re.match(r'^(?!\.)(((^|\.)[\w!#-\'*+\-/=?^-~]+)+|"([ !#-[\]-~]|\\[ -~])*")@(((?!-)[a-zA-Z\d-]+(?<!-)($|\.))+|\[(IPv6:)?(.*)\])(?<!\.)$',input()).groups()[7:];exec("if p:ipaddress.IPv%dAddress(p)"%(v and 6or 4))
except:v=5
print(v!=5)

IPaddress मॉड्यूल के लिए Python 3.3 की आवश्यकता होती है, जिसका उपयोग IPv4 और IPv6 पतों को मान्य करने के लिए किया जाता है।

कम गोल्फ वाला संस्करण:

import re, ipaddress

dot_string = r'(?!\.)((^|\.)[\w!#-\'*+\-/=?^-~]+)+'
    # negative lookahead to check that string doesn't start with .
    # each atom must start with a . or the beginning of the string

quoted_string = r'"([ !#-[\]-~]|\\[ -~])*"'
    # - is used for character ranges (also in dot_string)

domain = r'((?!-)[a-zA-Z\d-]+(?<!-)($|\.))+(?<!\.)'
    # negative lookahead/lookbehind to check each subdomain doesn't start/end with -
    # each domain must end with a . or the end of the string
    # negative lookbehind to check that string doesn't end with .

address_literal = r'\[(IPv6:)?(.*)\]'
    # captures the is_IPv6 and ip_address groups

final_regex = r'^(%s|%s)@(%s|%s)$' % (dot_string, quoted_string, domain, address_literal)

try:
    is_IPv6, ip_address = re.match(final_regex, input(), re.VERBOSE).groups()[7:]
        # if input doesn't match, calling .groups() will throw an exception

    if ip_address:
        exec("ipaddress.IPv%dAddress(ip_address)" % (6 if is_IPv6 else 4))
            # IPv4Address or IPv6Address will throw an exception if ip_address isn't valid
except:
    is_IPv6 = 5

print(is_IPv6 != 5)
    # is_IPv6 is used as a flag to tell whether an exception was thrown

बहुत अच्छा। मैं तुरंत कोई डुप्लिकेट पैटर्न नहीं ढूंढ सकता (एक छोटे चर पहचानकर्ता के साथ बदलने के लिए)। लेकिन ऐसा लगता है कि ALPHAसंवर्धित BNF और चार लीटर के निर्माण Quoted-stringमें सभी मामले असंवेदनशील हैं। क्या आप केस-असंवेदनशीलता को निर्दिष्ट करके और उन चार श्रेणी श्रेणियों में से किसी एक को खोदकर कुछ चार्ट बना सकते हैं? btw, अगर आप डर महसूस कर रहे हैं, तो क्या आप इसका संक्षिप्त विवरण दे सकते हैं कि आपने इसे कैसे विकसित किया है?
arnnew

@ कर्णदेव: धन्यवाद। मैंने कुछ कमेन्ट के साथ एक कम गोल्फ वाला संस्करण जोड़ा है, जो कुछ पेचीदा हिस्सों को समझाने की कोशिश कर रहा है। मैंने चार व्यक्तिगत टुकड़ों (डॉट-स्ट्रिंग, उद्धृत-स्ट्रिंग, डोमेन और पता-शाब्दिक) में रेगेक्स को विकसित किया, फिर उन्हें एक साथ मिला दिया और आईपी सत्यापन जोड़ा। कहने की जरूरत नहीं है, गोल्फ वास्तव में गड़बड़ हो गया।
GRC

कोई लंबाई सीमा नहीं?
माइकल रुशटन

2

PHP 5.4.9, 495

function _($e){return preg_match('/^(?!(?>"?(?>\\\[ -~]|[^"])"?){255,})(?!"?(?>\\\[ -~]|[^"]){65,}"?@)(?>([!#-\'*+\/-9=?^-~-]+)(?>\.(?1))*|"(?>[ !#-\[\]-~]|\\\[ -~])*")@(?!.*[^.]{64,})(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>\.(?2)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?3)){7}|(?!(?:.*[a-f0-9][:\]]){8,})((?3)(?>:(?3)){0,6})?::(?4)?))|(?>(?>IPv6:(?>(?3)(?>:(?3)){5}:|(?!(?:.*[a-f0-9]:){6,})(?5)?::(?>((?3)(?>:(?3)){0,4}):)?))?(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)(?>\.(?6)){3}))\])$/iD', $e);}

और बस आगे की रुचि के लिए, यहाँ RFC 5322 व्याकरण के लिए एक है जो नेस्टेड CFWS और अप्रचलित स्थानीय भागों के लिए अनुमति देता है:

(764)

function _($e){return preg_match('/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*(?2)")(?>(?1)\.(?1)(?4))*(?1)@(?!(?1)[a-z\d-]{64,})(?1)(?>([a-z\d](?>[a-z\d-]*[a-z\d])?)(?>(?1)\.(?!(?1)[a-z\d-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f\d]{1,4})(?>:(?6)){7}|(?!(?:.*[a-f\d][:\]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:|(?!(?:.*[a-f\d]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)(?>\.(?9)){3}))\])(?1)$/isD', $e);}

और अगर लंबाई-सीमा एक आवश्यकता नहीं है:

RFC 5321 (414)

function _($e){return preg_match('/^(?>([!#-\'*+\/-9=?^-~-]+)(?>\.(?1))*|"(?>[ !#-\[\]-~]|\\\[ -~])*")@(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>\.(?2)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?3)){7}|(?!(?:.*[a-f0-9][:\]]){8,})((?3)(?>:(?3)){0,6})?::(?4)?))|(?>(?>IPv6:(?>(?3)(?>:(?3)){5}:|(?!(?:.*[a-f0-9]:){6,})(?5)?::(?>((?3)(?>:(?3)){0,4}):)?))?(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)(?>\.(?6)){3}))\])$/iD', $e);}

RFC 5322 (636)

function _($e){return preg_match('/^((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*(?2)")(?>(?1)\.(?1)(?4))*(?1)@(?1)(?>([a-z\d](?>[a-z\d-]*[a-z\d])?)(?>(?1)\.(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f\d]{1,4})(?>:(?6)){7}|(?!(?:.*[a-f\d][:\]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:|(?!(?:.*[a-f\d]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)(?>\.(?9)){3}))\])(?1)$/isD', $e);}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.