[1] [DFN[stringprep]] は、 [[IETF]] の規格で[[文字列]]の[[正規化]]を行うために定義された[RUBY[枠組み][フレームワーク]]です。 [[IDN]] などの[[識別子]]で使われています。 * 仕様書 - [2] [CITE@en[RFC 3454 - Preparation of Internationalized Strings ("stringprep")]] * 処理モデル [3] [[Stringprep]] の処理は大きく4段階に分かれます。実装はこの順番に処理しなければ[['''なりません''']] [SRC[>>2 2.]]。この処理の入力は処理対象の[[文字列]]であり、 出力は処理結果の[[文字列]]か、または[[誤り]]のいずれかです。 [WEAK[([[誤り]]かつ[[文字列]]が返されることはありません。 [SRC[>>2 5.]])]] = [54] '''[RUBYB[写像]@en[mapping]]''': [[写像表]] (>>59) に基づき、 特定の[[文字]]をそれに対応する0[[文字]]以上の[[文字列]]へと[[写像]]します。 -- [58] [CODE(char)[[[SOFT HYPHEN]]]] の類の除去や[[大文字]]・[[小文字]]の統一 ([[case folding]]) などに使われます。 -- [61] [[写像]]は一度のみ行います。[[写像]]によって他の[[文字列]]に置き換えられた後、更にそれに[[写像]]を行うことは''しません''。 [SRC[>>2 3.]] = [55] '''正規化''': [[NFKC]] により正規化します。 プロファイルによってはこの作業を省略します。 = [56] '''禁止文字の検査''': [[禁止表]] (>>74) に含まれる[[文字]]を検出したら[[誤り]]とします。 = [57] '''Bidi に関する検査''': Unicode の [[bidi]] 算法に基づく表示で問題を起こす可能性があれば誤りとします。 プロファイルによってはこの作業を省略します。 [53] >>54 と >>55 では[[文字列]]の長さが増減することがあり、実装はこれに備えなければ[['''なりません''']] [SRC[>>2 2.]]。 * プロファイルと 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.]]。 * 写像表 [59] [[Stringprep]] で使用する[[写像表]]は[[プロファイル]]毎に規定します。 [60] 基本的には [[Stringprep]] 仕様で予め定義された表を使う[['''べきです''']]が、 必要なら独自に定義しても[['''構いません''']]。 [SRC[>>2 3.]] ** 附属書B.1 [62] [CITE@en[B.1 Commonly mapped to nothing]] [63] この[[表]]は、[CODE(charname)@en[[[SOFT HYPHEN]]]]、[CODE(charname)@en[[[ZERO WIDTH JOINER]]]]、 [[異体字選択子]]など、含まれていてもいなくても同じ[[識別子]]とみなされるべき [SRC[>>2 3.1]] [[文字]]を零文字に置き換える (削除する) ものです。 ** 附属書B.2 [64] [CITE@en[B.2 Mapping for case-folding used with NFKC]] [65] この[[表]]は、[[NFKC]] を使う場合のための[[大文字]]から[[小文字]]に変換するものです [SRC[>>2 3.2]]。 [73] この[[写像表]]は附属書B.3 (>>66) を >>71 により補強したものです [SRC[>>2 3.2]]。 ** 附属書B.3 [66] [CITE@en[B.3 Mapping for case-folding used with no normalization]] [67] この[[写像表]]は、[[正規化]]しない場合のための[[大文字]]から[[小文字]]に変換するものです [SRC[>>2 3.2]]。 [72] この[[写像表]]は [[Unicode 3.2]] の [[CaseFolding-3.txt]] に基づいています [SRC[>>2 3.2]]。 ** case folding の写像表 [68] [[大文字・小文字不区別]]としたい場合には、附属書B.2 (>>62) または附属書B.3 (>>64) を使って[[写像]]する[['''べきです''']] [SRC[>>2 3.2]]。 ;; [69] 現在の[[インターネット]]の[[プロトコル]]と[[応用]]では[[小文字]]が一般的なので、 [[大文字]]を[[小文字]]に変換しています [SRC[>>2 3.2]]。 [70] しかし独自の[[写像表]]を使いたいのなら、 [[UTR #21]] に基づく[['''べき''']]であり、 [[大文字]]から[[小文字]]に変換する[['''べき''']]です。 [[CaseFolding.txt]] に基づいて[[写像表]]を作る[['''べき''']]であり、完全な[RUBYB[大文字・小文字の写像]@en[full case mapping]] を使う ([[状態]] [[C]], [[F]], [[I]] を使う) [['''べき''']]です。 [SRC[>>2 3.2]] [71] [[NFKC]] を使うなら、 [[UTR #21]] では[[写像]]されてなくても処理が必要な[[文字]]があるため、 注意が必要です。 (一部の[[ギリシャ文字]]と多くの[[ラテン文字]]を含む[[記号]]が該当します。) これは、 = [VAR[a]] を入力とする = [VAR[b]] を、 [VAR[a]] を [[case folding]] し、 [[NFKC]] で[[正規化]]したものとする = [VAR[c]] を、 [VAR[b]] を [[case folding]] し、 [[NFKC]] で[[正規化]]したものとする = [VAR[c]] が [VAR[b]] と同じでなければ、 [VAR[a]] から [VAR[c]] への[[写像]]を追加する ... という方法で求められます。 [SRC[>>2 3.2]] * 禁止表 [74] [[Stringprep]] で使用する禁止[[文字]]の[[表]]は[[プロファイル]]毎に規定します。 ** 附属書C.1.1 [75] [CITE@en[C.1.1 ASCII space characters]] [76] [[ASCII]] に含まれる[[間隔文字]]の表で、 [CODE(charname)@en[[[SPACE]]]] だけが含まれています。 ** 附属書C.1.2 [77] [CITE@en[C.1.2 Non-ASCII space characters]] [78] [[非ASCII文字]]な[[間隔文字]]の表です。 ** 附属書C.2.1 [79] [CITE@en[C.2.1 ASCII control characters]] [81] [[ASCII]] に含まれる[[制御文字]]の表です。 ** 附属書C.2.2 [80] [CITE@en[C.2.2 Non-ASCII control characters]] [82] [[非ASCII文字]]な[[制御文字]]の表です。 ** 附属書C.3 [83] [CITE@en[C.3 Private use]] [84] [[私用域]]の[[符号位置]]の表です。 ** 附属書C.4 [85] [CITE@en[C.4 Non-character code points]] [86] [[非文字]]の[[符号位置]]の表です。 [93] [[PropList.txt]] [SRC[>>2 5.4]] に基づいているとみられます。 ** 附属書C.5 [87] [CITE@en[C.5 Surrogate codes]] [88] [[サロゲート]]の[[符号位置]]の表です。 ** 附属書C.6 [89] [CITE@en[C.6 Inappropriate for plain text]] [94] 普通の文章には登場しない[[文字]] [SRC[>>2 5.6]] が含まれています。 ** 附属書C.7 [90] [CITE@en[C.7 Inappropriate for canonical representation]] [95] [[IDC]] が含まれています。同じ[[文字]]が複数の方法で表現できてしまうので禁止するとされています。 [SRC[>>2 5.7]] ;; [96] それは誤解なような気がしますが。 [[IDS]] は[[文字]]そのものの表現方法ではないのでは。 ** 附属書C.8 [91] [CITE@en[C.8 Change display properties or are deprecated]] [97] [[レンダリング]]を操作するものや [[Unicode]] で[[非推奨]]とされているものが含まれています。 [SRC[>>2 5.8]] ** 附属書C.9 [92] [CITE@en[C.9 Tagging characters]] [98] 不可視な[[タグ文字]]が含まれています [SRC[>>2 5.9]]。 * 未定義符号位置の扱い [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]