[1] [[IDNA]] の [DFN@en[[CODE@en[ToASCII]]]]
は、[[国際化ラベル]]を[[ASCIIラベル]]に変換する[[演算]]です。

* 仕様書

[REFS[
- [2] [CITE@en[RFC 3490 - Internationalizing Domain Names in Applications (IDNA)]]
([[IETF]] [[提案標準]])
-- [22] [CSECTION@en[4.1 ToASCII]]
<http://tools.ietf.org/html/rfc3490#section-4.1>
- [24] [CITE@en-us[UTS #46: Unicode IDNA Compatibility Processing]] ([TIME[2010-10-30 01:01:25 +09:00]] 版) <http://unicode.org/reports/tr46/#ToASCII>
- [50] [CITE@en[URL Standard]] ([TIME[2016-08-25 16:02:43 +09:00]]) <https://url.spec.whatwg.org/#concept-domain-to-ascii>
- [28] [CITE@en[URL Standard]] ([TIME[2016-08-25 16:02:43 +09:00]]) <https://url.spec.whatwg.org/#dom-url-domaintoascii>
]REFS]

* UTS #46 ToASCII 演算

[25] [[UTS #46]] では[[ドメイン名]]に対して [[ToASCII]] [[演算]]が次の通り定義されています
[SRC[>>24]]。

[37] [[入力]]は、次のものです [SRC[>>24]]。
[FIG(list members middle)[
: [VAR[ドメイン名]] : [[Unicode文字列]]
: [VAR[[[UseSTD3ASCIIRules]]]] : [[boolean]]
: [VAR[[[CheckHyphens]]]] : [[boolean]]
: [VAR[[[CheckBidi]]]] : [[boolean]]
: [VAR[[[CheckJoiners]]]] : [[boolean]]
: [VAR[処理オプション]] : [[移行的処理]]または[[非移行的処理]]
: [VAR[VerifyDnsLength]] : [[boolean]]
]FIG]

[38] [[出力]]は、[[Unicode文字列]]または[[失敗]]です。

[39] 次のようにします [SRC[>>24]]。

[FIG(steps)[
= [26] ([VAR[結果]]、[VAR[誤り]]) を、[[Unicode IDNA互換性処理]]を実行した結果に設定します。
[FIG(list members middle)[
: [VAR[ドメイン名]] : [VAR[ドメイン名]]
: [VAR[[[CheckHyphens]]]] : [VAR[[[CheckHyphens]]]]
: [VAR[[[CheckBidi]]]] : [VAR[[[CheckBidi]]]]
: [VAR[[[CheckJoiners]]]] : [VAR[[[CheckJoiners]]]]
: [VAR[処理オプション]] : [VAR[処理オプション]]
: [VAR[[[UseSTD3ASCIIRules]]]] : [VAR[[[UseSTD3ASCIIRules]]]]
: [VAR[Punycode符号化]] : [[真]]
: [VAR[VerifyDnsLength]] : [VAR[VerifyDnsLength]]
]FIG]
= [33] [VAR[誤り]]が[[真]]なら、
== [48] [[失敗]]を返し、ここで停止します。
= [45] [VAR[結果]]を返します。
]FIG]

;; [27] [[仕様書]]では [[ToASCII]] の一部として説明されている操作の一部を、
ここでは [[Unicode IDNA互換性処理]]の一部としています。

[46] テストデータ:

[REFS[
- [47] [CITE[IdnaTest.txt]] ([TIME[2016-06-21 06:36:28 +09:00]]) <http://www.unicode.org/Public/idna/latest/IdnaTest.txt>
]REFS]

[58] 利用される場面は、[[Unicode IDNA互換性処理]]を参照。

* ドメインを ASCII に

[51] [DFN[[RUBYB[ドメインをASCIIに]@en[domain to ASCII]]]]する[[演算]]は、
[VAR[ドメイン]]と[VAR[厳密にする]] (既定値[[偽]]) について、
次のようにします [SRC[>>50]]。

[FIG(steps)[
= [52] [VAR[結果]]を、 [[UTS #46]] [[ToASCII]] の結果に設定します。
[FIG(list members middle)[

: [VAR[ドメイン名]] : [VAR[ドメイン]]
: [VAR[[[UseSTD3ASCIIRules]]]] : [VAR[厳密にする]]
: [VAR[[[CheckHyphens]]]] : [[偽]]
: [VAR[[[CheckBidi]]]] : [[真]]
: [VAR[[[CheckJoiners]]]] : [[真]]
: [VAR[[[移行的処理]]]] : [[偽]]
: [VAR[VerifyDnsLength]] : [VAR[厳密にする]]

]FIG]
= [53] [VAR[結果]]が[[失敗]]なら、
== [54] [[構文違反]]とします。
== [55] [[失敗]]を返します。
= [56] それ以外なら、
== [57] [VAR[結果]]を返します。
]FIG]

;; [63] [TIME[2017年2月][2017-02]]の改訂で[[移行的処理]]から[[非移行的処理]]に変更されました
[SRC[>>62]]。

[59] 利用される場面は、[[Unicode IDNA互換性処理]]を参照。

* 関連

[23] 逆の操作を行う [[ToUnicode]] [[演算]]もあります。

* 歴史

** IDNA2003 ToASCII 演算

*** 入力

[3] 
[[入力]]は、[[国際化名札]]、すなわち
[[Unicode]] [[符号位置]]の列と、[[旗]]
[CODE@en[[[AllowUnassigned]]]]、[[旗]]
[CODE@en[[[UseSTD3ASCIIRules]]]] です。
[SRC@en[RFC 3490 4.1]]

;; 
[6]
[[ドメイン名]]全体ではなく、構成する個々の[[名札]]が[[入力]]となります。
[[点]]を[[名札分離子]]として使う場合には、
[CODE(charname)@en[[[FULL STOP]]]],
[CODE(charname)@en[[[FULLWIDTH FULL STOP]]]],
[CODE(charname)@en[[[IDEOGRAPHIC FULL STOP]]]],
[CODE(charname)@en[[[HALFWIDTH IDEOGRAPHIC FULL STOP]]]]
を[[点]]と[['''しなければなりません''']]と規定されています。
[SRC@en[RFC 3490 3.1, 4.]]

*** 出力

[4] 
[CODE@en[[[ToASCII]]]] [[操作]]は、[[成功]]または[[失敗]]します。
[[成功]]した場合、[[ASCII名札]]、
すなわち [[ASCII]] [[符号位置]]の列を返します。
この[[ASCII名札]]は、入力 (>>3) の[[国際化名札]]と[[等価]]なものです。
[SRC@en[RFC 3490 4.1]]

;; 
[5]
[[ドメイン名]]中のいずれかの[[名札]]が
[CODE@en[[[ToASCII]]]] に[[失敗]]するなら、
その[[ドメイン名]]は[[国際化ドメイン名]]として使用[['''してはなりません''']]。
この[[失敗]]への対処は[[応用]]規定とされています。
[SRC@en[RFC 3490 4.1]]

;;
[7]
[[ドメイン名]]を >>6 により分割し、
それぞれの[[名札]]に [CODE@en[[[ToASCII]]]]
を適用した場合、更に[[点]]で結合して[[ドメイン名]]に戻すことになりますが、
[[ASCII]] [[ドメイン名]]とするためには、
[CODE(charname)@en[[[FULL STOP]]]] を使用[['''しなければなりません''']]。
[SRC@en[RFC 3490 3.1]]

*** 算法

[11] [[ToASCII]] [[演算]]の実際の処理は次の通りです [SRC@en[RFC 3490 4.1]]。

= [13] [[ASCII]] の範囲 
([CODE(char)[[[U+0000]]]]〜[CODE(char)[[[U+007F]]]])
の''外''の[[符号位置]]が含まれていれば、2 へ。
含まれていなければ、 3 へ。
=[14]  [[Nameprep]] を適用します ([[旗]]
[CODE@en[[[AllowUnassigned]]]] を使用します)。
[[誤り]]があれば、[[失敗]]とします。
= [15] [[旗]] [CODE@en[[[UseSTD3ASCIIRules]]]]
が設定されていれば、
== [[非LDH]] [[ASCII]] [[符号位置]]
([CODE(char)[[[U+0000]]]]〜[CODE(char)[[[U+002C]]]],
[CODE(char)[[[U+002E]]]], [CODE(char)[[[U+002F]]]],
[CODE(char)[[[U+003A]]]]〜[CODE(char)[[[U+0040]]]],
[CODE(char)[[[U+005B]]]]〜[CODE(char)[[[U+0060]]]],
[CODE(char)[[[U+007B]]]]〜[CODE(char)[[[U+007F]]]])
が含まれていないことを確認します。
= [16] 最初の[[文字]]や最後の[[文字]]が [CODE(char)[[[U+002D]]]]
でないことを確認します。
= [17] [[ASCII]] の範囲 
([CODE(char)[[[U+0000]]]]〜[CODE(char)[[[U+007F]]]])
の''外''の[[符号位置]]が含まれていれば、 5
に進みます。含まれていなければ、 6 に進みます。
= [18] [[ACE接頭辞]]で始まら''ない''ことを確認します。
= [19] [[Punycode]] により[[符号化]]します。
[[誤り]]があれば、[[失敗]]とします。
= [20] [[ACE接頭辞]]をはじめに追加します。
= [21] [[符号位置]]の数が1[[以上]]63[[以下]]であることを確認します。

[12] 確認して駄目だった場合にどうするとも書かれていませんが、どうするのでしょう・・・。
[[失敗]]となることを想定しているように見えますが、明記はされていません。

*** 性質

[8] [[ToASCII]] [[演算]]は次のような性質を持っています。

-[9] すべてが [[ASCII]] [[文字]]の[[名札]]を[[入力]]とした場合、
([[失敗]]するか、または) そのままの[[文字列]]を返します。
[SRC@en[RFC 3490 4.1]]
-[10] [CODE@en[[[ToASCII]]]] は[[冪等]]です (複数回適用しても、
同じ結果が得られます)。
[SRC@en[RFC 3490 4.1]]

*** 文脈

[35] [[IDNA2003]] [[ToASCII]] は次の場面で使われます。
[FIG(short list)[
- [CODE[[[dNSName]]]]
- [CODE[[[SRVName]]]]
]FIG]

**

[34] [CITE@en[Web Applications 1.0 r8780 Some reference updates, and an example of incumbent vs entry scripts]]
( ([TIME[2014-09-17 14:47:00 +09:00]] 版))
<https://html5.org/r/8780>

[36] [CITE@en[Cleanup definitions of domainToASCII() and domainToUnicode(). Give up… · whatwg/url@d18639f]]
([TIME[2015-08-18 12:14:00 +09:00]] 版)
<https://github.com/whatwg/url/commit/d18639f13cb710938f2251a8f0e40b637aa82823>

** [CODE(DOMi)@en[URL]] インターフェイス [CODE(DOMm)@en[domainToASCII]] 静的メソッド

[29] [CODE(DOMi)@en[URL]] [[インターフェイス]]の [DFN[[CODE(DOMm)@en[domainToASCII]]]]
[[静的メソッド]]は、次のようにしなければ[MUST[なりません]] [SRC[>>28]]。
[FIG(steps)[
= [30] [VAR[ドメイン]]を、必須の第1引数を [CODE(IDL)@en[USVString]] として解釈した結果に設定します。
= [31] [VAR[ASCIIドメイン]]を、[VAR[ドメイン]]に[[ホスト構文解析器]]を適用した結果に設定します。
= [32] [VAR[ASCIIドメイン]]が[[ドメイン]]でなければ、
== [40] [[空文字列]]を返します。
= [41] それ以外なら、
== [42] [VAR[ASCIIドメイン]]を返します。
]FIG]

[43] [[ドメインをASCIIに]]操作を直接呼び出さずに[[ホスト構文解析器]]を挟んでいますから、
[[パーセント符号化]]の処理、[[IPアドレス]]かどうかの判定、
不適切な[[ASCII文字]]の検査が追加で行われます。


[44] [CITE@en[Remove URL.domainToASCII and domainToUnicode]]
([[annevk]]著, [TIME[2016-10-19 21:04:17 +09:00]])
<https://github.com/whatwg/url/commit/2bd0f59b98024921ab90e628b7a526cca5abcb5f>

[49] [CITE@en[Editorial: point out that domain to ASCII fails on U+FFFD]]
([[annevk]]著, [TIME[2017-01-29 19:26:14 +09:00]])
<https://github.com/whatwg/url/commit/cf9854c9e03c12af19e2a249a0d9d6bec6a7419b>

[60] [CITE[Browser differences in IDNA ToASCII processing between ASCII and non-ASCII input — Anne’s Blog]]
([TIME[2017-02-15 00:28:42 +09:00]])
<https://annevankesteren.nl/2017/02/idna-toascii-differences>

[61] [CITE@en[Re: Unicode IDNA feedback]]
([[Anne van Kesteren]]著, [TIME[2017-02-13 18:33:47 +09:00]])
<https://lists.w3.org/Archives/Public/www-archive/2017Feb/0006.html>

[62] [CITE@en[Use Nontransitional_Processing for IDNA ToASCII]]
([[annevk]]著, [TIME[2017-02-20 18:51:49 +09:00]])
<https://github.com/whatwg/url/commit/f4d84a52e67b154b2d11e04889fe0a35a029c833>

[64] [CITE[Browser differences in IDNA ToASCII processing between ASCII and non-ASCII input — Anne’s Blog]]
([TIME[2017-03-05 20:38:44 +09:00]])
<https://annevankesteren.nl/2017/02/idna-toascii-differences>

[65] [CITE@en[IDNA: use proposed UTS46 flags to avoid breaking YouTube]]
([[annevk]]著, [TIME[2017-06-02 06:24:01 +09:00]])
<https://github.com/whatwg/url/commit/dc9d83106cada9af507bf37dee3973de97b020fd>

[67] [CITE@en[IDNA / UTS #46 "should" requirements (Bidi and Joiners) · Issue #110 · whatwg/url]]
([TIME[2017-09-03 21:20:27 +09:00]])
<https://github.com/whatwg/url/issues/110>

[68] [CITE@en[IDNA: realign once UTS46 revision 18 is final · Issue #313 · whatwg/url]]
([TIME[2017-09-03 21:23:44 +09:00]])
<https://github.com/whatwg/url/issues/313>

[69] [CITE@en[Address several IDNA issues by annevk · Pull Request #309 · whatwg/url]]
([TIME[2017-09-03 21:24:21 +09:00]])
<https://github.com/whatwg/url/pull/309>

[70] [CITE@en[IDNA · Issue #53 · whatwg/url]]
([TIME[2017-09-03 21:27:00 +09:00]])
<https://github.com/whatwg/url/issues/53>

[71] [CITE@en[Perhaps do not apply ToASCII for ASCII-only input · Issue #267 · whatwg/url]]
([TIME[2017-09-03 21:28:52 +09:00]])
<https://github.com/whatwg/url/issues/267>

[72] [CITE@en[IDNA: UTS46 revision 19 is part of Unicode 10]]
([[annevk]]著, [TIME[2017-06-23 02:33:33 +09:00]])
<https://github.com/whatwg/url/commit/b128ba9111c68ad767b472d77d0ada9ef85366ef>

[73] [CITE@en[IDNA: UTS46 revision 19 is part of Unicode 10 by annevk · Pull Request #325 · whatwg/url]]
([TIME[2017-09-03 21:31:50 +09:00]])
<https://github.com/whatwg/url/pull/325>

[66] [CITE@en[Continue to use Nontransitional processing for IDNA]]
([[TRowbotham]]著, [TIME[2018-07-23 21:38:43 +09:00]])
<https://github.com/whatwg/url/commit/6800342832fdf99caa265d0106cf984123716d9d>

[74] [CITE@en[Preserve use of Nontransitional processing for IDNA by TRowbotham · Pull Request #404 · whatwg/url]]
([TIME[2018-07-26 22:30:53 +09:00]])
<https://github.com/whatwg/url/pull/404>