• Showing Page History #34524

Show page source of 2chtrip #34524

= 2ch トリップ仕様(抄)

掲示板にトリップ機能を搭載したものの、利用者から"2chトリップ検索スレで探してもらったトリップが使えない"などの苦情が出てしまった。そんな管理者・サイト作成者のために、2chトリップと同じものを出力する方法をまとめてみました。

== 仕様概要

2ch掲示板システム(以降2ch)の投稿処理スクリプト(以下bbs.cgi)に実装されているトリップの仕様において、重要なものは以下の通りです。

  * POSIX準拠のCRYPT(3)に基づいています。Perl, PHP などではcrypt(key,salt)により容易に利用できます。ハッシュアルゴリズムはDESベースのものを用います。すなわちCRYPT(3)のSalt引数にて$により指定できる拡張暗号化アルゴリズム(MD5など)は利用しません。
  * 2ch は Shift_JIS ベースで構成されたサイトです。すなわち記事投稿(カキコ)フォームにて入力された文字列は基本的に Shift_JIS にて bbs.cgi に渡されます。必然的にトリップキーも Shift_JIS エンコードであることが前提となります。2chはトリップキーの入力に対し制限を課していません。
  * bbs.cgi はマルチバイト非対応Perl5にて記述されています。受け取ったトリップキーはマルチバイト処理を施さず、バイト(オクテット)単位で取り扱うようにします。
  * Salt は実装上の歴史的理由により、トリップキーの2文字目および3文字目から変換表により一意に決定し、ドット, スラッシュ, 数字, アルファベット大文字, アルファベット小文字の 64 種で構成される文字 2 文字で表し、CRYPT(3)に渡す必要があります。

以下、2ch実装の現状ではあるが仕様不備であると考えられる項目を挙げます。[http://www.geocities.jp/trip_chaser/2ch_mojibake.html 2ちゃんねる文字化け対策@レアトリップ配信所]も参考にしてください。

  * bbs.cgi の文字エスケープ(HTMLのメタ文字を置換)は、トリップキーに対しても行われます。また、bbs.cgi の文字エスケープ規則は独特(あえて言うなら不完全)です。
  * bbs.cgi の語句置換処理(いわゆるNGワード)もまた、トリップキーに対して行われます。置換の対象語句はマルチバイトであるにもかかわらず、非マルチバイトにて置換が行われるため、一見置換対象でない文字列に対しても置換が行われることがあります。
  * bbs.cgi 稼働サーバOS(FreeBSD)のCRYPT(3)には、他OSと互換性がなく対策も困難である仕様が存在します。FreeBSDではキーバイト列に 0x80 が含まれている場合にそれをキー文字列の終端(0x00)と見なし、以降のバイト列は 0x00 であるかのごとく処理してしまいます。一部のShift_JIS全角文字がこの仕様に抵触します。

また、クライアント(ブラウザ)依存の問題として、クライアントが扱う文字コードは純粋な Shift_JIS ではないという点があります。これに関しては掲示板システム実装者が積極的に関知する必要はありません。

== 掲示板システムに2chトリップを実装するために

基本的に、以下の項目に従えば、2chトリップと互換であると見なされます。逆に、以下を逸脱している場合には、2chトリップと同じものを出力することは困難となります。

  * トリップキーは Shift_JIS エンコードにてCRYPT(3)に入力する必要があります。サイトが EUC, UTF-8 など、Shift_JIS以外で構成されている場合には、トリップキーを適宜文字コード変換処理により Shift_JIS に変換してください。
  * トリップキー中の空白文字などをトリップキー終端と見なしてはいけません。空白も含めて最短8バイトをトリップキーとして扱う必要があります。実際に入力されたトリップキーが8バイト未満の場合はその限りではありません。
  * トリップキーにはHTMLエスケープおよびSQLエスケープを施してはいけません。CRYPT(3)の出力は、入力されるトリップキーを"サニタイズ"していると考えてください。システム上エスケープを施す必要がある場合は、エスケープ処理より先にトリップキーの抽出分離を行ってください。
  * Salt は 2ch 規則に従って生成します。後述します。
  * トリップキーが2文字の場合には、Salt生成のためにトリップキーの3文字目が使用できないため、Salt2文字目は "H" とします。
  * トリップキーが1文字の場合には、Saltは "H." とします。
  * 表示するトリップは、CRYPT(3)により得られた出力文字列(13文字)の末尾10文字を取り出して用いてください。出力の先頭2文字は入力のSaltと同じもの、すなわちトリップキーの一部であるため、外部に出力してはいけません。

2ch と同様の結果を得るためには、さらに以下の項目を実施することになります。いずれを施さなくても、利用者側でキーを一部改竄することにより対応可能なので、必須ではありません。

  * トリップキーに対しても、非マルチバイト処理にてエスケープ・NGワード置換を行います。
  * トリップキー中の 0x80 を認識し、それ以降の文字を切り落とすことにより、2chサーバ制限と同様の結果を得ることができます。

=== Perl(マルチバイト非対応)

=== Perl(use Encode)

=== PHP4

== Salt処理

|| ||0||1||2||3||4||5||6||7||8||9||A||B||C||D||E||F||
||0x00||.||.||.||.||.||.||.||.||.||.||.||.||.||.||.||.||
||0x10||.||.||.||.||.||.||.||.||.||.||.||.||.||.||.||.||
||0x20||.||.||.||.||.||.||.||.||.||.||.||.||.||.||.||/||
||0x30||0||1||2||3||4||5||6||7||8||9||A||B||C||D||E||F||
||0x40||G||A||B||C||D||E||F||G||H||I||J||K||L||M||N||O||
||0x50||P||Q||R||S||T||U||V||W||X||Y||Z||a||b||c||d||e||
||0x60||f||a||b||c||d||e||f||g||h||i||j||k||l||m||n||o||
||0x70||p||q||r||s||t||u||v||w||x||y||z||.||.||.||.||.||
||0x80||.||.||.||.||.||.||.||.||.||.||.||.||.||.||.||.||
||0x90||.||.||.||.||.||.||.||.||.||.||.||.||.||.||.||.||
||0xA0||.||.||.||.||.||.||.||.||.||.||.||.||.||.||.||.||
||0xB0||.||.||.||.||.||.||.||.||.||.||.||.||.||.||.||.||
||0xC0||.||.||.||.||.||.||.||.||.||.||.||.||.||.||.||.||
||0xD0||.||.||.||.||.||.||.||.||.||.||.||.||.||.||.||.||
||0xE0||.||.||.||.||.||.||.||.||.||.||.||.||.||.||.||.||
||0xF0||.||.||.||.||.||.||.||.||.||.||.||.||.||.||.||.||

== 歴史

=== Salt の扱い

いわゆる新鯖Salt

{{{ code perl
if($FORM{'FROM'} =~ /([^\#]*)\#(.+)/){
    my $main_message = $1;
    my $handle_pass = $2;
    my $change_salt = substr($handle_pass, , 1) . "H";
    $handle_pass = substr(crypt($handle_pass, $change_salt), -10);
}
}}}


|| ||0||1||2||3||4||5||6||7||8||9||A||B||C||D||E||F||
||0x00||G||H||I||J||K||L||M||N||O||P||Q||R||S||T||U||V||
||0x10||W||X||Y||Z||a||b||c||d||e||f||g||h||i||j||k||l||
||0x20||m||n||o||p||q||r||s||t||u||v||w||x||y||z||.||/||
||0x30||0||1||2||3||4||5||6||7||8||9||A||B||C||D||E||F||
||0x40||G||A||B||C||D||E||F||G||H||I||J||K||L||M||N||O||
||0x50||P||Q||R||S||T||U||V||W||X||Y||Z||a||b||c||d||e||
||0x60||f||a||b||c||d||e||f||g||h||i||j||k||l||m||n||o||
||0x70||p||q||r||s||t||u||v||w||x||y||z||.||/||0||1||2||
||0x80||G||H||I||J||K||L||M||N||O||P||Q||R||S||T||U||V||
||0x90||W||X||Y||Z||a||b||c||d||e||f||g||h||i||j||k||l||
||0xA0||m||n||o||p||q||r||s||t||u||v||w||x||y||z||.||/||
||0xB0||0||1||2||3||4||5||6||7||8||9||A||B||C||D||E||F||
||0xC0||G||H||I||J||K||L||M||N||O||P||Q||R||S||T||U||V||
||0xD0||W||X||Y||Z||a||b||c||d||e||f||g||h||i||j||k||l||
||0xE0||m||n||o||p||q||r||s||t||u||v||w||x||y||z||.||/||
||0xF0||0||1||2||3||4||5||6||7||8||9||A||B||C||D||E||F||

== See also
  * 2ちゃんねる文字化け対策@レアトリップ配信所[[BR]]http://www.geocities.jp/trip_chaser/2ch_mojibake.html
  * ◆ 全サーバトリップ統一作戦[[BR]]http://qb5.2ch.net/operate/kako/1067/10672/1067245837.html

== 用語集

||語||略語など||概要||
||CRYPT(3)||crypt||POSIX||
||DES||DES||元来は56ビットキーによる64ビットデータのブロック暗号。CRYPT(3)およびトリップでは、0をキーで25回繰り返して暗号化した結果をハッシュとして用いる。||
||HTMLエスケープ|| ||ここに書くのか?||
||SQLエスケープ|| ||' および \ を処理?||
||エスケープ||escape||かきかけ||
||トリップ||trip, hash||トリップキーから一意に変換された10文字の文字列を指す。それぞれの文字は64通りの集合(数字, アルファベット大文字, アルファベット小文字, ピリオド, スラッシュ)にて構成される。[[BR]]あるいは2chに実装されたID表示システムの通称。ひろゆき命名。||
||トリップキー||key||えーと、めんどくせー||