コミュニティ

RFC 5322 & 5321に沿ったメールアドレス(local-part)に使える文字まとめ

メールアドレスの仕様について気になったので調べたことをまとめました。
そしてテストデータを少しばかり考えてみました。
何か違っている所があればご指摘いただけると助かります。
いやぁ…RFC準拠のメールアドレスのテストって難しいですね。
(というかRFC読むのが難しかった…です)

現在(2019/01/20)のメールアドレスに関わるRFC

※ 6854と7504は一部追加・変更のようなので、多くの部分は5322と5321となっているようです。

(余談)そもそもRFCとは?

IETF(Internet Engineering Task Force)が発行している、技術仕様などについての文書群です。
IETFはインターネット技術の標準化などを行っています。

※ RFC → Requests For Commentsの略称
※ IETF公式:IETF | Internet Engineering Task Force
※ 参考:RFC【Request For Comments】 - IT用語辞典

(余談)RFCは廃止・更新されるもの

RFCは技術仕様の標準的なものが書かれています。
当たり前のことですが技術は進化するものなので、廃止・更新されていきます。

例えばRFC 2822について。

スクリーンショット 2019-01-20 18.22.42.png
このRFC 2822は他のRFCと以下のような関係になっています。

  • Obsoletes: RFC 822
    • RFC 822を廃止して、RFC 2822になりました
  • Obsoleted by: RFC 5322
    • RFC 2822は廃止され、RFC 5322になりました
  • Updated by: RFC 5335, RFC5336
    • RFC 5335, RFC 5336はRFC 2822を一部更新したものです

なので、現在どのRFCが最新なのか?については、↑のサイトからたどることができます。
便利ですね。

【インターネットはこうして創られている~IETFの仕組み】 第3回:RFCの読み方 - INTERNET Watch Watch
第2回 Internet StandardsとRFC (6/6)

メールアドレスに関わるRFC

さて、メールアドレスに関わるRFCですが、冒頭に書いたように以下のものが現在の最新のようです。

※ この記事ではメール本文の構造などは取り扱わず、メールアドレス(xxx@xxx)がどういう仕様なのか?に注目したものなので、RFC5321とRFC5322を参考しています。

RFCに基づくメールアドレスの仕様

そもそもWikipediaにわかりやすく書かれてました!
パッと見たい方はぜひご参考ください。
メールアドレス - Wikipedia

↓はRFC本文や他の方のブログなどを読みながら書いたものになります。

① メールアドレスの構造

メールアドレスは以下の構造で定義されています。
local-part@domain

② 文字数

それぞれ最大文字数が定義されています。

  • local-part: 最大64文字
  • domain: 最大253文字(RFCでは、255文字と書かれているが、別途識別に文字が2文字分必要なので)
  • local-part@domain 全体: 最大254文字 (RFCでは、256文字と書かれているが別途識別に文字が2文字必要なので)

ということで、local-partに最大の64文字使った場合は、domainは254 - 64 - 1で189文字となります(- 1は@分)。
もちろん、domainに253文字使った場合は、254 - 253 - 1 でlocal-partが0文字になってしまうので、現実的にはdomainが253文字使われるというケースはなさそうですかね(- 1は@分)。
また、local-partの定義的にはnullが許容されてなさそうです。
最低1文字は必要そうです。

③ local-partに使える文字の種類

全角文字は使えません。
すべて半角になります。

  1. 無条件で使える: 81文字
    1. アルファベット(大文字 & 小文字)52文字 → A~Z, a~z
    2. 数字10文字 → 0~9
    3. 記号19文字 → ! # $ % & ' * + - / = ? ^ _ ` { | } ~
  2. 先頭と末尾以外、かつ連続しなければ使える(末尾=@の直前): 1文字
    1. ドット → .
  3. ダブルクオートでくくると使える: 93文字
    1. 無条件で使えるもの81文字
    2. ドット(連続しよう可) → .
    3. 記号10文字 → ( ) , : ; < > @ [ ]
  4. ダブルクオートでくくる & バックスラッシュをつけると使える: 97文字
    1. ダブルクオートでくくると使えるもの93文字
    2. バックスラッシュと連続すると使える4文字(最後の2つは半角スペースとタブです) → " \ タブ

メールアドレスのテストデータ例

何かのご参考になればと思います。

メールアドレスとして成立するもの

local-partのデータ 適用されるルール(数字は③をもとに) 補足
abcdefghijklmnopqrstuvwxyz 1.1 アルファベット小文字 -
ABCDEFGHIJKLMNOPQRSTUVWXYZ 1.1 アルファベット大文字 -
0123456789 1.2 数字 -
!#$%&'*+-/=?^_{|}~` 1.3 記号 -
a.b 2.1 ドット -
"abcdefghijklmnopqrstuvwxyz" 3.1 ダブルクオート + アルファベット小文字 -
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" 3.1 ダブルクオート + アルファベット大文字 -
"0123456789" 3.1 ダブルクオート + 数字 -
"!#$%&'*+-/=?^_{|}~`" 3.1 ダブルクオート + 記号 -
"." 3.2 ダブルクオート + ドット -
".." 3.2 ダブルクオート + ドット(連続) ダブルクオートでくくると連続使用可能
" ()*,:;<>@[]" 3.3 ダブルクオート + 記号 -
"\a\A\0\!\." 4.1 ダブルクオート + バックスラッシュ + 3.3までに成立したもの テストデータよく考えたほうが良いです
"\\"\ \ " 4.2 ダブルクオート + バックスラッシュ + 記号 スペースとタブを含んでいます
0123456789012345678901234567890123456789012345678901234567890123 - 64文字

メールアドレスとして成立しないもの

テストデータ 適用されるルール(数字は③をもとに) 補足
.aaa 2.1 ドット .先頭はNG
aaa. 2.1 ドット .が最後はNG
a..a 2.1 ドット ダブルクオートでくくらずに.が連続するのはNG
() 3.3 ダブルクオート ダブルクオートでくくらずに()を使用するのはNG
"aaa"a 4.2 ダブルクオート + バックスラッシュ + 記号 ダブルクオートは最初と最後に無いとだめ。(使う場合は\を使う)
- 空はNG
01234567890123456789012345678901234567890123456789012345678901234 - 65文字以上はNG
"あいうえお" - 全角文字はNG

注意点

このテストをもしするとなったとき、気をつけたほうがいいだろうなぁ…と思うことをまとめました。

① テストデータの取扱い: プログラム実行時に気をつける

記号系、特にダブルクオートやシングルクオートなのですが、テストデータ生成やDBに値を入れるときに、プログラムで自動実行すると意図したテストデータが入らない、プログラム実行時にエラーが起きる、といったことが発生します。
$ #などはもちろん、// /*というような、プログラムのコメントアウトに使われたりするものも取扱いに注意が必要です。
状況に応じて、手動で操作することをおすすめします。

② テストデータの取扱い: エクセルなどの場合、コピー操作やシングルクオートに気をつける

エクセルやGoogleスプレッドシートでは、先頭にシングルクオートを入力すると、先頭が0の数字を表示してくれる機能があります。
なのでこれをうっかりしていると、先頭のシングルクオートがなくなってたり…なんてこともあるかもしれないです。
表計算ソフトなどで保管している場合は、コメントなど残しておいたほうが良さそうですね。
※ 参考: Excelで先頭の「0」が消えるのを表示させる4つの方法|Office Hack

③ 本当にRFCに準拠するのかを考える

ここまで書いておいて、おいおいって感じですけどね(笑)
RFC 5821では、local-part部の大文字と小文字は区別する、と明記されています(しかし推奨しないとも書かれています)。
でも、多くのサービスでは大文字と小文字区別されていませんよね。
また記号についても、ダブルクオートやバックスラッシュを使えばたくさんの記号やスペースが使えますが、本当に対応すべきなのか考えたほうが良いかもしれません(文字数についてもそうですね)。

(余談) Gmailのエイリアスについて

別のアドレスやエイリアスからメールを送信する - Gmail ヘルプ
Gmailのエイリアス機能ありますよね。
local-partの直後に+を書くことで、複数のメールアドレスのように管理できる機能で、テストに関わる方はよく使っている機能の1つかと思います。
このエイリアスを使って、メールアドレスが全体が300文字以上になったアドレスに送信したところ送信 & 受信することができました。
ちなみに送信したアプリケーションはMacのThunderbirdでした。
RFC的にはメールアドレスの制限があるんですが、そうじゃないパターンでも使えるようになっているってことですよね。
便利だなぁと思います。
なのでメールアドレスを作成するときは、RFCよりも少し厳しめに制限をかけておくけど、送信・受信のときはメールアドレスの文字数をチェックしない…といった対応のほうが対応できる幅は広がりそうですね。

(余談) RFC 5322, 5321を読むためのメモ

RFCでは以下の用語が使われていました。
確認用のメモとして残しておきます。

local-partで使用できる文字について

local-part = dot-atom / quoted-string / obs-local-part
① dot-atom
dot-atom = [CFWS] dot-atom-text [CFWS]
dot-atom-text = 1*atext *("." 1*atext)
atext = ALPHA / DIGIT /"!" / "#" /
"$" / "%" / "&" / "'" / "*" / "+" /"-" / "/" / "=" / "?" /"^" / "_" /"`" / "{" / "|" / "}" / "~"

② quoted-string
quoted-string = [CFWS] DQUOTE *([FWS] qcontent)[FWS] DQUOTE [CFWS]
qcontent = qtext / quoted-pair
qtext = %d33 / %d35-91 / %d93-126 / obs-qtext
quoted-pair = ("\" (VCHAR / WSP)) / obs-qp
obs-qtext = obs-NO-WS-CTL
obs-NO-WS-CTL = %d1-8 / %d11 / %d12 / %d14-31 / %d127
obs-qp = "\" (%d0 / obs-NO-WS-CTL / LF / CR)

③ obs-local-part
obs-local-part = word *("." word)
word = atom / quoted-string

※ ALPHA, DIGIT, VCHAR, CR, LF, CRLF, HTAB, SP, WSP, DQUOTE についてはRFC 5324を参考にする
ABNF - Wikipedia

  • ALPHA → アルファベットの大文字と小文字
  • DIGIT → 0~9の数字
  • VCHAR → ASCIIで印字される文字 ASCII - Wikipedia
  • %d33 → ASCII表で10進数で33の部分。つまり!
  • %x41 → ASCII表で16進数で41の部分。つまりa

参考サイト

この記事を書くにあたって以下のサイトを参考にさせていただきました。

fusic
個性をかき集めて、驚きの角度から世の中をアップデートしつづける。
https://fusic.co.jp/
ユーザー登録して、Qiitaをもっと便利に使ってみませんか。
  1. あなたにマッチした記事をお届けします
    ユーザーやタグをフォローすることで、あなたが興味を持つ技術分野の情報をまとめてキャッチアップできます
  2. 便利な情報をあとで効率的に読み返せます
    気に入った記事を「ストック」することで、あとからすぐに検索できます
この記事は以下の記事からリンクされています
zako1560Laravelのemailバリデーションからリンク
rainbow___0RFC emaillバリデーションからリンク
kaizen_nagoyaメールアドレス考からリンク
コメント

@foom 記号19文字のところに「`」が消えていたのと、
記号10文字のところに、「*」が紛れ込み記号11文字と間違えて表記していました。
編集リクエストいただき編集しました。
ありがとうございました。

dot-atom の atext の記号の順番を変更; atext で使えず quoted-string の qtext で使える記号は10種(アスタリスクを修正) by foom 2020/02/16 01:08

あなたもコメントしてみませんか :)
すでにアカウントを持っている方は
ユーザーは見つかりませんでした