-
Notifications
You must be signed in to change notification settings - Fork 51
/
Copy pathrfc5321.py
63 lines (56 loc) · 1.92 KB
/
rfc5321.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import re
# ([!#-'*+/-9=?A-Z^-~-]+(\.[!#-'*+/-9=?A-Z^-~-]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")
# @
# ([!#-'*+/-9=?A-Z^-~-]+(\.[!#-'*+/-9=?A-Z^-~-]+)*|\[[\t -Z^-~]*])
#
# [a-zA-Z0-9!#$%&'*+/=?^_`{|}~-] == Alphanumeric characters and most special characters except [ (),.:;<>@\[\]\t]
# [a-zA-Z0-9 !#$%&'()*+,./:;<=>?@\[\]^_`{|}~\t-] == All printable characters except for " and \
# [\t -~] == All printable characters
# [a-zA-Z0-9 !"#$%&'()*+,./:;<=>?@^_`{|}~\t-] == All printable characters except for the following characters []\
RFC5321_REGEX = re.compile(
r"""
^
(?P<local>
[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*
|
"(?:[a-zA-Z0-9 !#$%&'()*+,./:;<=>?@\[\]^_`{|}~\t-]|\\[\t -~])+"
)
@
(?P<domain>
[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*
|
\[[a-zA-Z0-9 !"#$%&'()*+,./:;<=>?@^_`{|}~\t-]*\]
)
$
""",
re.VERBOSE | re.ASCII,
)
def validate(email_str: object) -> bool:
"""Validate a string as a RFC5321 email address."""
if not isinstance(email_str, str):
return False
match = RFC5321_REGEX.match(email_str)
if not match:
return False
local, domain = match.group("local", "domain")
# Local part of email address is limited to 64 octets
if len(local) > 64:
return False
# Domain names are limited to 253 octets
if len(domain) > 253:
return False
for domain_part in domain.split("."):
# DNS Labels are limited to 63 octets
if len(domain_part) > 63:
return False
return True
if __name__ == "__main__":
import timeit
N = 100_000
tests = (("basic", "[email protected]"),)
print("benchmarking")
for name, val in tests:
all_times = timeit.repeat(
f"validate({val!r})", globals=globals(), repeat=3, number=N
)
print(f"{name} (valid={validate(val)}): {int(min(all_times) / N * 10**9)}ns")