mb_detect_encoding() は文字コードの妥当性検証として使用できるか(その3)

遅くなりましたが、以下の続きです。

今回は ISO-2022-JPISO-2022-JP-MS、UTF-16、UTF-16BE、UTF-16LE について、mb_check_encoding() と mb_detect_encoding() を比較しました。調査した PHP のバージョンは、5.2.9 で、前々回(mb_detect_encoding() は文字コード判定として使用できるか(その1))の Patch を適用したもので調査しました。通常の PHP の結果とは一致しません。
間違いを発見した方はコメントなどでご指摘ください。

ISO-2022-JP

正規表現
mb_detect_encoding()\A([\x00-\x1a\x1c-\x7f]|\x1b\x24[\x40\x42]([\x21-\x7e][\x21-\x7e])+|\x1b\x24\x28[\x40\x42\x44]([\x21-\x7e][\x21-\x7e])+|\x1b\x28\x42)*\z
mb_check_encoding()正規表現では記述不可
相違点
mb_check_encoding() では、ISO-2022-JP の判定を正規表現で記述できませんでした。mb_detect_encoding() での範囲は TRUE になりますが、その他の FALSE となるべきバイト列の場合でも TRUE を返します。 例えば、"1b", "1b00", "1b2400" などは FALSE となるべきですが、mb_check_encoding() の判定では TRUE となります。

ISO-2022-JP-MS

正規表現
mb_detect_encoding()\A([\x00-\x1a\x1c-\x7f]|\x1b\x24[\x40\x42]([\x21-\x7e][\x21-\x7e])+|\x1b\x24\x28[\x40\x42\x44]([\x21-\x7e][\x21-\x7e])+|\x1b\x28\x42|\x1b\x28\x4a[\x00-\x1a\x1c-\x7f]+|\x1b\x28\x49[\x00-\x1a\x1c-\x7f]+\x1b\x28\x42)*\z
mb_check_encoding()正規表現では記述不可
相違点
ISO-2022-JP と同様に ISO-2022-JP-MS の判定を正規表現で記述できませんでした。不正なバイト列でも TRUE を返す場合があります。

UTF-16

正規表現
mb_detect_encoding()常に FALSE
mb_check_encoding()\A([\x00-\xd7\xe0-\xff][\x00-\xff]|[\xd8-\xdb][\x00-\xff][\xdc-\xdf][\x00-\xff])*\z(※)
※ mb_check_encoding() では一部の文字が FALSE になります。
相違点
mb_detect_encoding() では、常に FALSE を返します。 mb_check_encoding() は、Little Endian における、BOM(fffe) が FALSE になります。

UTF-16BE

正規表現
mb_detect_encoding()常に FALSE
mb_check_encoding()\A([\x00-\xd7\xe0-\xff][\x00-\xff]|[\xd8-\xdb][\x00-\xff][\xdc-\xdf][\x00-\xff])*\z
相違点
mb_detect_encoding() では、常に FALSE を返します。

UTF-16LE

正規表現
mb_detect_encoding()常に FALSE
mb_check_encoding()\A([\x00-\xff][\x00-\xd7\xe0-\xff]|[\x00-\xff][\xd8-\xdb][\x00-\xff][\xdc-\xdf])*\z
相違点
mb_detect_encoding() では、常に FALSE を返します。

まとめ

mb_check_encoding() は、前回に書いた通り多くの注意点がある上、TRUE と返すべき文字を FALSE と返すことがあります(その逆もあります)。このため、致命的ではありませんが、文字コードの妥当性判定に使用する場合には注意する必要があります。そこで、mb_detect_encoding() が mb_check_encoding() の代替にならないかと考えて調べてみましたが、最初に結論として書いた通り、現状では使えません。
以下に現状(PHP 5.2.9) mb_detect_encoding() の問題点を挙げておきます。PHP 5.2.10 と PHP 5.3.0 も公開されましたが、同様です。