このアルゴリズムの概要

(1)隣接する2バイト(i番目とi+1番目)の組の頻度分布(256x256のマップ)を文字コード既知のテキストデータについて計算すると、文字コードごとに明らかに大きな差が出る(元記事を参照)。これを辞書データとして保管する。
(2)この文字コードの辞書データを65536(=256^2)次元のベクトルとしてとらえ、それぞれと、文字コード未知のテキストデータを一部切り出して同様に計算した65536次元のベクトルの内積を取る。辞書データは同じノルムに規格化しておく。*1こうすることで、未知データがどれくらいそれぞれのエンコードに似ているかが計算できる。未知データとの内積が一番大きいエンコードを採用。

メリット

いったん辞書データを作ってしまえば、あとは計算コストは小さい。テキストの一部(〜100バイトの並び)に対しての内積の計算コストはほとんど無視できるレベルに小さい。アイデアはコロンブスの卵的でクール。このままで実用的かどうかはともかく、文字コードの詳細な知識を用いずに判別出来るのがコンセプト的に面白い。

改善の余地

辞書データのサイズが大きい。一つ、すぐ考えられる改良は、内積の線形性(a \cdot (x+y) = a \cdot x + b \cdot y)を用いて、一つの辞書ベクトルデータをその他から差し引いて消すことだが、サイズが3/4になるだけで劇的とは言いがたい。辞書データのマップがぱっと見からして大きく異なることを考えると、辞書データの特徴を上手く抽出してもっとサイズを小さく出来そうに思われる。

*1:ノルム1だと小さすぎて要素を表示するときなどに扱いにくいので、私はノルムが65536になるように規格化した。