[1] [DFN[stringprep]] は、 [[IETF]] の規格で[[文字列]]の[[正規化]]を行うために定義された[RUBY[枠組み][フレームワーク]]です。 [[IDN]] などの[[識別子]]で使われています。 * 仕様書 - [2] [CITE@en[RFC 3454 - Preparation of Internationalized Strings ("stringprep")]] * 文字列準備作業 [3] Stringprep の処理は大きく 4段階に分けられます。処理に対する入力は文字列で、 出力は処理結果の文字列または[[誤り]] [WEAK[(のいずれか)]] です。 = '''写像''': 写像表に基づき[[文字]]から[[文字列]]へ写像します。 1文字が0文字以上の任意の長さの文字列に変換されます。 [CODE(char)[[[SOFT HYPHEN]]]] の類の除去や[[大文字]]・ [[小文字]]の統一などに使われます。 使用する写像表はプロファイル毎に規定します。 = '''正規化''': [[NFKC]] により正規化します。 プロファイルによってはこの作業を省略します。 = '''禁止文字の検査''': 禁止文字を検出したら誤りとします。 禁止文字はプロファイル毎に規定します。 = '''Bidi に関する検査''': Unicode の [[bidi]] 算法に基づく表示で問題を起こす可能性があれば誤りとします。 プロファイルによってはこの作業を省略します。 * プロファイルと Unicode の版 [5] [[RFC 3454]] は [[Unicode 3.2]] に基づいています。 基本的に RFC 3454 とそれに基づくプロファイルは Unicode 3.2 に基づき設計されることになります。 RFC 3454 は新しい版の Unicode で使うことが想定されていないと明確に述べています [SRC[>>2 1.2]]。 [48] RFC 3454 は新しい版の Unicode に対応した新しい版のプロファイルを作ってもプロファイルを使う[[プロトコル]]を全面改訂したりしなくて済むように、 写像表などの非互換変更を禁じたり、 未定義符号位置の処理に関する規定 (>>4) を設けたりしています。 [11] [[IDNA2003]] でも、新しい版を使って[[正規化]]しては[['''ならない''']]と明確に規定されています。 ;; [CITE@en[RFC 3490 - Internationalizing Domain Names in Applications (IDNA)]] * 文字レパートリ [49] [[Stringprep]] の[[プロファイル]]は、利用する[[文字レパートリ]]を選択しなければ[['''なりません''']] [SRC[>>2 1.2]]。 ただし、現在規定されているのは [[Unicode 3.2]] [[レパートリ]] [SRC[>>2 A.]] のみで、他の選択肢はありません。 [50] [[文字レパートリ]]は固定されたものではなく、将来の改訂で[[文字]]が追加されることがあります [SRC[>>2 1.2]]。 ;; [51] といっても唯一定義されている「[[Unicode 3.2]]」[[レパートリ]]が拡張されることは流石にないでしょう・・・。 [52] [[Unicode 3.2]] [[文字レパートリ]]における[[未定義]]の[[符号位置]]の一覧も [[RFC]] で定義されています [SRC[>>2 A.]]。実装は [[Unicode 3.2]] の仕様では''なく''、この [[RFC]] の一覧に基づいて処理しなければ[['''なりません''']] [SRC[>>2 A.]]。 * 未定義符号位置の扱い [4] まだ[[文字]]が割当てられておらず、 将来割当てられるかもしれない[[符号位置]]についての規定もあります。 [12] Stringprep のプロファイルを適用する文字列は大別して [DFN[[[蓄積文字列]]]]と[Q[[[照会]]]]の2種類があります。 蓄積文字列はデータベースに登録する項目名のようなもので、 照会はデータベースから項目を取出すために指定する項目名のようなものです。 前者は未定義符号位置を含んではなりませんが、 後者は含んでいても構いません。 この制限によってあるプロファイルが作られた時点で未定義な符号位置が使われていても意図した結果が得られる可能性が幾分高くなります。 [13] [[IDNA]] には [[AllowUnassigned]] [[フラグ]]が規定されています。 [[Nameprep]] において未定義の[[符号位置]]をどう扱うかはこの[[フラグ]]に依存します。 * プロファイルの定義 [36] [[プロファイル]]は、次のものを含んでいなければ[['''なりません''']] [SRC[>>2 1.2]]。 - [37] [[プロファイル]]の想定する適用可能性 - [38] [[文字レパートリ]] - [39] 利用する[[写像]]の[[表]] -- [40] [[Stringprep]] 共通のもの -- [41] 独自のもの (ある場合) - [42] [[正規化]]の方法 (利用する場合) - [43] 禁止する[[文字]]の[[表]] -- [45] [[Stringprep]] 共通のもの -- [46] 独自のもの (ある場合) - [44] [[bidi]] 文字列検査の方法 (利用する場合) [32] 関係する2つの[[プロファイル]]がそれぞれ別々の[[プロファイル]]を使っていると、 [[文字列]]をどう[[正規化]]するか、何が認められるかが違っているため、 [[相互運用]]が難しくなります。ですから、新しい[[プロファイル]]を無闇に作らず、 既存の[[プロファイル]]を流用するよう、強く求められています [SRC[>>2 1.2]]。 [35] [[Stringprep]] は[[プロファイル]]間でできるだけ表を共有することを意図しており、 従って[[プロファイル]]が独自に[[表]]を作ることもできるとはいえ、 極力 [[Stringprep]] 仕様で定義されている[[表]]の組み合わせに依ることが望ましいです [SRC[>>2 1.2]]。 [33] [[プロファイル]]においてできるだけ多くの[[文字]]を利用可能としたい場合、 可能な限り、[[文字]]の利用を禁止するのではなく他の[[文字]]に変換することを選ぶべきです。 [SRC[>>2 1.2]] [34] [[Stringprep]] によって[[文字]]関係の[[規格]]の逝かれているところを「修正」 することもあるいはできるかもしれませんが、それは行う[['''べきではありません''']] [SRC[>>2 1.2]]。 ** 登録 [6] [[Stringprep]] の[[プロファイル]]は [[IESG]] の審査を経て [[RFC]] 化され、 [[IANA]] に登録されることになっています。[[プロファイル]]は [[IANA]] に登録されなければ[['''なりません''']] [SRC[>>2 1.2]]。 * プロファイルの一覧 [47] ,名前 ,版 ,状態 ,出典 ,[[iSCSI]] ,1 ,現行 (IETF 提案標準) ,"[[RFC 3722]], [IANAREG]" ,[[Nameprep]] ,1 ,現行 (IETF 提案標準) ,"[[RFC 3491]], [IANAREG]" ,[[Nodeprep]] ,1 ,現行 (IETF 提案標準) ,"[[RFC 3920]], [IANAREG]" ,[[Policy MIB Stringprep]] ,1 ,現行 (IETF 提案標準) ,"[[RFC 4011]], [IANAREG]" ,[[Resourceprep]] ,1 ,現行 (IETF 提案標準) ,"[[RFC 3920]], [IANAREG]" ,[[SASLprep]] ,1 ,現行 (IETF 提案標準) ,"[[RFC 4013]], [IANAREG]" ,[[trace]],1,現行,"[[RFC 4505]], [IANAREG]" - [IANAREG] IANA 登録簿 [CITE[Stringprep Profiles]] [Q[(2011-01-12)]] ** trace [22] [DFN[trace]] は、 [[SASL]] の [CODE[[[ANONYMOUS]]]] で用いられる [[Stringprep]] [[プロファイル]]です。 [[RFC 4504]] で定義され、 [[IANA]] に登録されています。 ;; [23] 一つ前の [[RFC 2245]] は[[非ASCII文字]]を認めておらず、 [[Stringprep]] も使っていませんでした。 *** 仕様書 - [24] [CITE@en[RFC 4505 - Anonymous Simple Authentication and Security Layer (SASL) Mechanism]] -- [25] '''''' -- [27] ** その他 [16] [CITE@en[draft-ietf-krb-wg-utf8-profile-01 - Preparation of Internationalized Strings Profile for Kerberos UTF-8 Strings]] [19] [CITE@en[draft-zeilenga-ldapbis-strmatch-02 - Internationalized String Matching Rules for X.500]] [21] >>16、>>19 は [[Internet Draft]] 止まりで [[RFC]] 化されていませんが、 [[GNU Libidn]] で実装されています。 * プロファイルの比較 [7] ,名前 ,文字レパートリ ,写像 ,== ,== ,== ,正規化 ,禁止 ,== ,== ,== ,== ,== ,== ,== ,== ,== ,== ,== ,bidi ,未割当 , , ,[ABBR[3454 B.1] [除去]] ,[ABBR[3454 B.2] [小文字化 (NFKC)]] ,[ABBR[3454 B.3] [小文字化]] ,その他 , ,[ABBR[3454 C.1.1] [[CODE(char)[U+0020]]]] ,[ABBR[3454 C.1.2] [その他の間隔]] ,[ABBR[3454 C.2.1] [C0 制御文字]] ,[ABBR[3454 C.2.2] [その他の制御文字]] ,[ABBR[3454 C.3] [私用文字]] ,[ABBR[3454 C.4] [代理文字]] ,[ABBR[3454 C.5] [非文字]] ,[ABBR[3454 C.6] [ルビ]] ,[ABBR[3454 C.7] [IDS]] ,[ABBR[3454 C.8] [bidi]] ,[ABBR[3454 C.9] [タグ]] ,その他 , , ,[[iSCSI]] ,[[Unicode 3.2]] ([ABBR[3454 A] [Unicode 3.2]]) ,○ ,○ , , ,[[NFKC]] ,○ ,○ ,○ ,○ ,○ ,○ ,○ ,○ ,○ ,○ ,○ ,あり ,○ ,[ABBR[3454 A.1] [Unicode 3.2 未割当]] ,[[Nameprep]] ,[[Unicode 3.2]] ([ABBR[3454 A] [Unicode 3.2]]) ,○ ,○ , , ,[[NFKC]] , ,○ , ,○ ,○ ,○ ,○ ,○ ,○ ,○ ,○ , ,○ ,[ABBR[3454 A.1] [Unicode 3.2 未割当]] ([[AllowUnassigned]] 依存) ,[[Nodeprep]] ,[[Unicode 3.2]] ([ABBR[3454 A] [Unicode 3.2]]) ,○ ,○ , , ,[[NFKC]] ,○ ,○ ,○ ,○ ,○ ,○ ,○ ,○ ,○ ,○ ,○ ,あり ,○ ,[ABBR[3454 A.1] [Unicode 3.2 未割当]] ,[[Policy MIB Stringprep]] ,[[Unicode 3.2]] ([ABBR[3454 A.1] [Unicode 3.2 未割当]]) ,○ , , , ,[[NFKC]] , , ,○ ,○ ,○ ,○ ,○ ,○ ,○ ,○ ,○ , , , ,[[Resourceprep]] ,[[Unicode 3.2]] ([ABBR[3454 A] [Unicode 3.2]]) ,○ , , , ,[[NFKC]] , ,○ ,○ ,○ ,○ ,○ ,○ ,○ ,○ ,○ ,○ , ,○ ,[ABBR[3454 A.1] [Unicode 3.2 未割当]] ,[[SASLprep]] ,[[Unicode 3.2]] ,○ , , ,[ABBR[3454 C.1.2] [間隔]] -> [ABBR[3454 C.1.1] [[CODE(char)[U+0020]]]] ,[[NFKC]] , ,○ ,○ ,○ ,○ ,○ ,○ ,○ ,○ ,○ ,○ , ,○ ,3454 A.1 ,[[trace]],[[Unicode 3.2]], , , , , , , ,○,○,○,○,○,○, , ,○, ,○, ** iSCSI の追加禁止文字 [8] [[RFC 3722]] 6.1. の表 (共通入力機構不適切文字): ,符号位置 ,文字名称 ,[CODE(char)[[[U+3002]]]] ,[CODE(char)[[[IDEOGRAPHIC FULL STOP]]]] [26] [[RFC 3722]] 6.2. の表 (禁止済み ASCII 文字): ,符号位置 ,[CODE(char)[[[U+0000]]]]〜[CODE(char)[[[U+002C]]]] ,[CODE(char)[[[U+002F]]]] ,[CODE(char)[[[U+003B]]]]〜[CODE(char)[[[U+0040]]]] ,[CODE(char)[[[U+005B]]]]〜[CODE(char)[[[U+0060]]]] ,[CODE(char)[[[U+007B]]]]〜[CODE(char)[[[U+007F]]]] ** Nodeprep の追加禁止文字 [9] [[RFC 3920]] A.5. の表: ,[CODE(char)[[[U+0022]]]] ,[CODE(char)[[[QUOTATION MARK]]]] ,[CODE(char)[[[U+0026]]]] ,[CODE(char)[[[AMPERSAND]]]] ,[CODE(char)[[[U+0027]]]] ,[CODE(char)[[[APOSTROPHE]]]] ,[CODE(char)[[[U+002F]]]] ,[CODE(char)[[[SOLIDUS]]]] ,[CODE(char)[[[U+003A]]]] ,[CODE(char)[[[COLON]]]] ,[CODE(char)[[[U+003C]]]] ,[CODE(char)[[[LESS-THAN SIGN]]]] ,[CODE(char)[[[U+003E]]]] ,[CODE(char)[[[GREATER-THAN SIGN]]]] ,[CODE(char)[[[U+0040]]]] ,[CODE(char)[[[COMMERTIAL AT]]]] ** メモ [10] なんか >>7 と同じ表が既に存在しているし[AA[orz]] [CITE[Stringprep Profiles]] * 実装 [14] [CITE[Unicode::Stringprep - search.cpan.org]] ( ([TIME[2011-03-06 19:17:21 +09:00]] 版)) [17] [[GNU Libidn]] は >>16、>>19 に対応しているらしいです。 * IDNA2008 との関係 [28] [[IDNA2003]] は [[Stringprep]] の[[プロファイル]]である [[Nameprep]] を使っていましたが、 [[IDNA2008]] は [[Nameprep]] を使わずにすべて独自に定義しています。 [[Nameprep]] と [[IDNA2008]] にはまったく互換性がありません。 [29] [[IDNA2008]] の [[RFC]] では、他の [[Stringprep]] を使う[[応用]]である[[セキュリティ]]系プロトコルとは要件が異なり ([[ドメイン名]]は分かりやすいことが重要だが[[合言葉]]は分かりにくいことが重要)、 共通の仕組みを用いることは必ずしも好ましくないと指摘しています。 - [30] [CITE@en[RFC 5890 - Internationalized Domain Names for Applications (IDNA): Definitions and Document Framework]] ([TIME[2011-02-05 07:34:19 +09:00]] 版) - [31] [CITE@en[RFC 5894 - Internationalized Domain Names for Applications (IDNA): Background, Explanation, and Rationale]] ([TIME[2011-02-05 07:34:29 +09:00]] 版) * テスト・ケース [18] [CITE[Nameprep and IDNA Test Vectors]] [20] [CITE@en-US[Savannah Git Hosting - libidn.git/tree - tests/]] * メモ [15]