Bonkura - Kenny

SIerで働く文系SEの記録

【読書メモ】プログラマのための文字コード技術入門_その2

プログラマのための文字コード技術入門の読書メモその2。
バイナリエディタを使った符号化バイト列の確認も、おまけにやってみました。

プログラマのための文字コード技術入門 (WEB+DB PRESS plus) (WEB+DB PRESS plusシリーズ)

プログラマのための文字コード技術入門 (WEB+DB PRESS plus) (WEB+DB PRESS plusシリーズ)

代表的な符号化文字コード

ASCII

1文字:7ビットの1バイト(最上位ビットは0)

JIS X 0201

  • 1文字:8ビットの1バイ
  • ラテン文字集合と片仮名集合(半角カタカナ)を定めている
  • 濁点半濁点は、合わせて一文字と扱われない。

JIS X 0208

Unicode(=UCS)

  • 世界中に文字を一つの表に収めるべく開発された。
  • 符号の構造 4バイトの符号:UCS-4
    郡>面>区×点
  • 郡:郡00~郡7F まで存在する。
    UTF-16@2バイトで表すことの出来ない面は使われない為、郡00以外は使われない。
  • 面:面00~面FFまで存在
    面00→基本多言語面BMP) 。最もよく使う、基本的な文字・記号のほとんどが含まれる。

  • 符号の表し方 接頭辞「U+」+4桁~6桁の数字

ex1) U+4E00
→面00(BMP)の区4E,点00
ex2) U+20B9F
→面02の区0B,点9F
ex3) U+10FFFF
→面17の区FF,点FF@UTF-8で指し示すことが出来る符号位置の上限

  • 文字名の定義
    各文字について一意な名前を与えている。
    Unicode内で識別子としてだけでなく、他の符号化文字集合との対応を取る為にも使われる。

代表的な文字符号化形式

EUC-JP

  • ASCIIとJIS X 0208を同時に用いる8ビットの符号化形式。UNIXでよく用いられる。
  • GL領域はASCIIを呼び出した状態で固定(0x7F以下の値(=1バイト)はASCIIの文字を表す)
  • GR領域はJIS X 0208が呼び出され、2バイトで表される。
  • ただし、 補助漢字JIS X 0212を呼び出す場合は切り替えにシングルシフトが使われるので、まるで3バイトで表されているかのように見えるが、シングルシフトはあくまで制御文字。
    ※自動的にJIS X 0208に戻る。
  • 1バイト~3バイトまでの混合と行って差し支えない。

Shift_JIS

  • 半角1バイト、全角2バイトで表現
  • 0x5c、すなわちASCIIのバックスラッシュが特殊な意味を保つ場合がある。
    ex)"表"は第2バイトが0x5cなのでprint"表"で"がエスケープされてしまう危険がある。

UTF-16

  • 16ビットの符号単位を用いる。
    BMPの文字は符号単位1つ(2バイト)、BMP以外の文字は2つの組み合わせ(4バイト)
  • バイト単位の入出力でバイト順を識別するためのBOMが必要。
  • Windowsのメモ帳で保存する時の「Unicode」はUTF-16を指す。

UTF-8

  • ASCIIとの互換性あり。
  • 1バイト~3バイトの可変長マルチバイトで表される。
    ASCII:1バイト 日本語:3バイ
  • バイト単位の入出力を行うため、バイト順の影響がない。

コード変換

符号化されたテキストの文字を変えずに、コードだけ変換する。コード変換が正しく行われたかは、変換元・変換先の文字コード定義に照らして判断する。

変換ツール

  • iconv
iconv -l
iconv -f UTF-8 -t SHIFT_JIS tokyo.txt
nkf -g tokyo.txt
nkf -w --overwrite tokyo.txt

変換の方式

文字コードの自動判別

  • BOMによる判別
  • エスケープシーケンスによる判別
  • バイト列の特徴を読む
    →完璧ではないので、理想は明示的に用いている文字コードを指定すること。

Webと文字コード

HTML

文字参照:キーボードから入力できない等の理由で直接書くことの出来ない文字を間接的に記す方法。
文字参照をHTML文書中に書くことで、対応する文字をブラウザで表示する。

書き方:「$#」と「;」でUnicodeの符号位置を挟む。
ex )テキストエディタを開き「©」と入力→拡張子をhtmlとして保存→ブラウザで開く

フォームで入力したテキストをWebサーバに送る際の文字コードは?
 →フォームを含むHTML文書と同じ符号化方式が使われる。

  • 文字コードの指定 head要素のmeta要素を用いて指定する。

URL

URIではASCIIを用いる。ASCIIにない文字は直接書くことはできない。
URL符号化(URLエンコーディング):記号%の後に2桁の16信数を書く
ex) %B1%EA → B1 EA という2バイトを表す。

Webブラウザによっては、ステータスバーなどに表示する符号化されたURLをUTF-8等に従って複合化し、あたかも日本語URLが実現されているように見せているが、実際にやり取りされるのはURLエンコーディングされた値となる。

HTTP

  • HTMLやCXMLでの文字コード指定の問題点

    • 複合するファイルの中に複合に必要な文字コードが宣言してある。(鍵付きの箱の中に鍵が入っている)
         ※文字コードの宣言部分はASCIIとして解釈できるという前提を置くことで回避。上位互換の文字コードを使えば問題なく読み込める。
    • コード変換に弱い(コード変換しても宣言している文字コードは変わらない)
  • HTTPヘッダのContent-typeフィールドで文字コードを明示する。

  • HTMLとHTTPヘッダで違う文字コードが指定されていたら?→HTTPヘッダが優先されるとHTMLの仕様で規定されている。

  • どうやって設定するの? →Webサーバに依存。

はまりやすい落とし穴と調査

文字化け対策

改行コード混在の対策

改行コードが混在した場合→nkfを用いる事で綺麗に揃える事が出来る。 * -Lu:改行コードをLFに変換 * -Lw:改行コードをCRLFに変換 * -Lm:改行コードをCRに変換

円記号問題

→円記号とバックスラッシュが入れ替わることでプログラムに不具合を引き起こす問題

波ダッシュ問題

SJISUTF-8SJISで変換をかけた時に、文字化けが発生する問題

ASCIIで試す!文字に対応するバイト列の確認方法。(おまけ)

f:id:knygt15437:20160418221400j:plain

f:id:knygt15437:20160418221358j:plain

長くなりましたが、以上です。これを読めば実戦で使えるかと言うと微妙ですが、基礎の基礎は把握できたかなぁと思います。