RFC に準拠したメールアドレスについて
はじめに
メールアドレスのバリデーションをする際、 RFC に準拠していないメールアドレスについても考慮しないといけなかったりする。
その時思ったのが、そもそも RFC に準拠した RFC とは何ぞやとなった。なので、この記事ではメールアドレスの形式について RFC ではどう定められているかを見ていく。
どの RFC で定められているのか
メールアドレスの形式については RFC 5321 (Simple Mail Transfer Protocol, SMTP) と RFC 5322 (Internet Mesage Format, IMF) で定められている。今回は後者の RFC 5322 の section 3.4.1 Addr-Spec Specification を見ていく。目標は有効なメールアドレスの形式を理解すること。つまり addr-spec
の本質部分を理解することである。
ABNF 記法で書かれた定義を読み取っていく
目標を達成することは、 ABNF を読み取っていくことに他ならない。ドキュメントに倣い ABNF 記法で書き連ねていき、その説明を載せていく。
ABNF 記法(RFC 5234)はすでに知っているものとする。
また、今回は obs-* の定義には触れない。というのも廃止された構文として section 4 で(互換性のため?)定義されているためである。
前提となるもの(ABNF編)
ABNF 記法の RFC の Core Rules で今回使うものを載せておく。
SP = %x20
HTAB = %x09
; horizontal tab
WSP = SP / HTAB
; white space
CR = %x0D
; carriage return
LF = %x0A
; linefeed
CRLF = CR LF
; Internet standard newline
DQUOTE = %x22
; " (Double Quote)
DIGIT = %x30-39
; 0-9
ALPHA = %x41-5A / %x61-7A ; A-Z / a-z
VCHAR = %x21-7E
; visible (printing) character
前提となるもの(IMF編)
Folding White Space and Comments
section 3.2.2 にある空白とコメントについての定義。
FWS = ([*WSP CRLF] 1*WSP) / obs-FWS
; Folding white space
ctext = %d33-39 / ; Printable US-ASCII
%d42-91 / ; characters not including
%d93-126 / ; "(", ")", or "\"
obs-ctext
ccontent = ctext / quoted-pair / comment
comment = "(" *([FWS] ccontent) [FWS] ")"
CFWS = (1*([FWS] comment) [FWS]) / FWS
comment
というのは (
と )
ではさまれたものを指し、 CFWS
は空白改行と comment で作られるものを指している。ここで定義しているのは、今回知りたいこと本質からずれるため、簡単に流しておく。
Atom
section 3.2.3 にある Atom についての定義。ココが本質的な部分となる。
atext = ALPHA / DIGIT / ; Printable US-ASCII
"!" / "#" / ; characters not including
"$" / "%" / ; specials. Used for atoms.
"&" / "'" /
"*" / "+" /
"-" / "/" /
"=" / "?" /
"^" / "_" /
"`" / "{" /
"|" / "}" /
"~"
atom = [CFWS] 1*atext [CFWS]
dot-atom-text = 1*atext *("." 1*atext)
dot-atom = [CFWS] dot-atom-text [CFWS]
specials = "(" / ")" / ; Special characters that do
"<" / ">" / ; not appear in atext
"[" / "]" /
":" / ";" /
"@" / "\" /
"," / "." /
DQUOTE
atext
というのは、アルファベット(A-Z と a-z)と数字(0-9)といくつかの記号(!#$%&'*+-/=?^_`{|}~)のどれか一文字を表す。
例
- 33-4
- nandeya
- hanshin!
- kankei_naiyaro???
- ###++++--
- {$//=^~}
dot-atom-text
と(本質的な部分で一致している dot-atom
) については、 atext
が一文字以上連なったものの後に、0個以上の、 .
と atext
が一文字以上連なったものを表している。
例
- osushi
- hito.#no.{okane}.|de|.yakiniku!.tabetai++++
Quoted characters & Quoted Strings
section 3.2.1 の Quoted characters である。
quoted-pair = ("\" (VCHAR / WSP)) / obs-qp
バックスラッシュ \
と半角スペースまたは可視文字の組み合わせである。つまりエスケープを表している。
一方、 section 3.2.4 の Quoted Strings を見ていく。
qtext = %d33 / ; Printable US-ASCII
%d35-91 / ; characters not including
%d93-126 / ; "\" or the quote character
obs-qtext
qcontent = qtext / quoted-pair
quoted-string = [CFWS]
DQUOTE *([FWS] qcontent) [FWS] DQUOTE
[CFWS]
qtext
がコメントにあるように VCHAR
から \
と "
を省いた文字である。 qcontent
が qtext
と quoted-pair
のどちらかを指し、 quoted-string
はダブルクォーテーションで囲まれた 0 文字以上の qcontent
である。
例
- "star-hoshii"
- "5000-"cho"-en\hoshi"
addr-spec について
今回解読する addr-sepc
は下記のように定義されている。
addr-spec = local-part "@" domain
これは local-part
と domaim
が @
で結び付けられている。
local-port について
local-part = dot-atom / quoted-string / obs-local-part
local-part
で使えるものは、一つ目として dot-atom
つまり、 A-Z, a-z, 0-9, !#$%&'*+-/=?^_{|}~ の文字であり、
.を使う際は最初と最後にが来ずかつ連続して使われない文字列である。 二つ目の
quoted-stringについては、ダブルクォーテーションでくくられている場合、 エスケープ処理が必要な文字があるが
VCHAR` 全部使うことができる。
例
- among-us.zutto.yaritai!
- 18782+18782=37564
- "(x+y)^2=x^2+2xy+y^2"
- "...................."
domain について
domain = dot-atom / domain-literal / obs-domain
domain-literal = [CFWS] "[" *([FWS] dtext) [FWS] "]" [CFWS]
dtext = %d33-90 / ; Printable US-ASCII
%d94-126 / ; characters not including
obs-dtext ; "[", "]", or "\"
domain
で使えるのは、 local-part
と同じように dot-atom
と、 [
と ]
と \
を使っていない文字列で [
と ]
で囲まれたものである。
例
- [????????.........########]
結論
以上のことから、使われる文字は制限されているものの、 "
や []
で囲むことによってほとんどの文字が使える(初めて知った)。
補足
文字数制限
addr-spec = local-part "@" domain
これを満たしている addr-spec
なら何でもメールアドレスとして使えるのか?と言われると No である。それは文字数制限があるからである。
文字数については、今まで見てきた RFC 5322 (IMF) では規定されていなく RFC 5321 (SMTP) の方で規定されている。
section 4.5.3.1 にはこう記載されている。
4.5.3.1.1. Local-part
The maximum total length of a user name or other local-part is 64
octets.4.5.3.1.2. Domain
The maximum total length of a domain name or number is 255 octets.
なので local-part
部分の最大文字数は 64 文字であり、 domain
部分の最大文字数は 255 文字である。
ただ RFC 3696 によると、
A DNS label may be no more than 63 octets long.
とあるので domain
部分は 63 文字以下にしておいた方が無難である。
Discussion