LoginSignup
0
0

More than 1 year has passed since last update.

latin1のようでlatin1でない(TextDecoder)

Posted at

TextDecoderでバイト列を文字列に変換しようとしたら、意外な形で引っかかってしまいました。

TL; DR

  • TextDecoderlatin1asciiと指定しても、実際にはWindows-1252として処理される
  • latin1とWindows-1252では、0x80 - 0x9Fのマッピングが違う
  • バイナリ文字列を配列に起こすなど、0x80 - 0x9FをU+0080 - U+009Fにそのまま対応させたい用途には使えない

TextDecoderとは

TextDecoderは、配列に入った数値の組を、文字コードとして解釈して文字列に変換するためのクラスです。対応するエンコードはUnicode系だけでなく豊富に用意されていて、たとえば日本語用のSJIS、EUC-JP、ISO-2022-JPも存在します(JavaScriptコードとしてテーブルを持たずに、これらのエンコードを解釈できる、ということになります)。

latin1を使ってみたら

その中にlatin1があったので、atobの結果を投げ込んでバイト配列にしてみたのですが…おかしな値を出していることに気づいてしまいました。

調べてみた結果

先ほど挙げた エンコードリストのページを見たところ、latin1asciius-asciiなどのように指定した場合、実際にはWindows-1252(Wikipedia)というエンコーディングが使われることが判明しました。この2つの違いは、

  • latin1…0x80 - 0x9Fには制御コードが入っている(UnicodeでもU+0080 - U+009Fに同じ形で入っている)
  • Windows-1252…0x80 - 0x9Fには一部を除いて文字が入っている(Unicodeと単純なマッピングにはならない)

というもので、latin1で書かれた普通の文書であれば0x80 - 0x9Fの文字がないので問題にはならないのですが、atobの結果など256通りのバイトパターンが全て使われている場合には大問題となってしまいます。

結論

TextDecoderで得られた結果のうち、マッピングが違う文字だけあとから置換する、というようなことを試してみたりもしたのですが、結局は素直にforString.fromCharCodeを動かして文字列を継ぎ足す、という原始的な方法が最速だったのでそれでいいかなとなっています。

0
0
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0