文字コード

ここでは文字コードに関する事項を整理した。

 

1.文字コードに関する用語

■文字コード
文字とそれに対応するビット組み合わせを対応づける規則。
広い意味で使われることが多く、文字コード≒符号化文字集合≒符号化方式と解釈しても問題ない。
※実態として、それぞれの用語は利用シーンによって意味が変わってくるので、厳密な定義にこだわり過ぎるのは無意味である。

■符号化文字集合
文字集合を定義しその集合内の各文字に一意の符号化表現を関連付ける規則。
JISX0201、JISX0208、ISO/IEC10646等。

■符号化方式
符号化文字集合の文字を実際にコンピュータが利用できるバイトデータへ変換する符号化方式。
EUC-JPやShift_JIS、UTF-8のように符号化文字集合を組み合わせて運用する方式。
ISO-2022-JP、EUC-JP、Shift_JIS等。

■ASCII
7ビットの1バイトコードで1文字を表すISO/IEC646の基礎となる文字コード。
英数字、記号、制御文字を含む。
アメリカで開発されたもので「American Standard Code for Information Interchange」の略。

■全角半角
本来は印刷の用語で、印字上の長さの単位であり、文字の印字幅はフォント次第であり、文字コードの概念とは関係がない。
ただし、実態としては半角=JISX0201(ASCII+カタカナ)を指すようである。

2.文字コードの変遷

以下に文字コードの国際規格の変遷と、符号化文字集合、符号化方式の関係を示す。

charset01.PNG

※特記事項

・ASCIIに対するJISX0201の違いは「バックスラッシュ」⇒「円記号」、「チルダ」⇒「オーバーライン」の2文字である。

・ISO/IEC8859-1は文字種の少ないヨーロッパ圏向けの符号化文字集合。

・JISX0212はJISX0208に足りない文字を補うための符号化文字集合で、通称は「補助漢字」。
 JISX0212は単独で使われず、JISX0208と組み合わせて使用できるよう設計してある。

・JISX0213はJISX0212の問題点を踏まえてJISX0208を改めて拡張しなおしたもの。
 完成版のJISX0208とみなすことができる。

3.符号化方式の特性

符号化方式 別名 特性
EUC-JP 日本語EUC

ASCIIとJISX0208を同時に用いる8ビットの符号化方式。
「Extended UNIX Code Packed Format for Japanese」の略。

ISO-2022-JP JISコード

ASCII、JISX0201ラテン文字、JISX0208を混在して使用することのできる7ビットの符号化方式。
文字集合をエスケープシーケンスにて切り替えを行う。
電子メールによく使用される。

Shift_JIS シフトJIS、SJIS、シフト符号化表現 JISX0201の8ビット符号の隙間にJISX0208を変形のうえ押し込んだもの。1980年代を通じて各社のPCで広く実装され、事実上の標準。
CP932 MS932、Window-31J Windowsの機種依存文字付きのShift_JIS。
UTF-16  

「Unicode Transformation Format 16」の略。

UTF-8  

1つの符号位置の表現に1バイトから4倍とまでの長さをとり得る可変長の符号化方式。ASCIIと互換性がある。
UTF-16やUTF-32と異なり、BOMコードは不要だが、付与される場合もある。

 

4.実際のバイトデータ確認

実際にJavaプログラムを実行し、文字列を各種符号化方式で出力した結果を確認する。

(1)対象文字列

 「abcあ①123」を各種符号化方式で出力する。
  ・abc:ASCIIコード英字
  ・123:ASCIIコード数字
  ・あ:日本語文字
  ・①:日本語文字機種依存

(2)ソースコード

package codingdemo.charset;

import java.io.UnsupportedEncodingException;

public class CharsetDemoMain {

    public static void main(String[] args) {

        String targetString = "abcあ①123";
        String[] encoding = new String[] { "Shift_JIS", "MS932", "EUC-JP", "ISO-2022-JP", "UTF-8", "UTF-16" };
        byte[] result;
        {
            for (int i = 0; i < encoding.length; i++)
                try {
                    result = targetString.getBytes(encoding[i]);
                    System.out.println(encoding[i] + ":\t" + getHexString(result));
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
        }
    }

    private static String getHexString(byte[] data) {
        StringBuffer sb = new StringBuffer();
        for (byte b : data) {
            String s = Integer.toHexString(0xff & b);
            if (s.length() == 1) {
                sb.append("0");
            }
            sb.append(s);
        }
        return sb.toString();
    }

}

(3)実行結果

Shift_JIS:    61626382a03f313233
MS932:    61626382a08740313233
EUC-JP:    616263a4a23f313233
ISO-2022-JP:    6162631b2442242221291b2842313233
UTF-8:    616263e38182e291a0313233
UTF-16:    feff00610062006330422460003100320033

charset02.PNG

・各コードはバイトデータを16進数で表現(2文字で1バイト)
・UTF-16には先頭BOMコードが必須のため、「FEFF」が付与される
・UTF-16以外の符号化方式においてASCIIコードは同一のバイトデータとなる
・ISO-2022-JPにおけるASCII文字⇒JISX0208文字の境界にエスケープシーケンス3バイト[ESC+$+B]が付与される
・ISO-2022-JPにおけるJISX0208文字⇒ASCII文字の境界にエスケープシーケンス3バイト[ESC+(+B]が付与される

5.文字コード変換ツール等

(1)iconv

$ iconv -f EUC-JP -t SHIFT_JIS EUC.txt > out.txt

・Centos7の標準パッケージにはiconvツールは含まれていた
・実行結果は標準出力へ出力される
・コマンド実行例の「EUC.txt」はEUC-JPで記載したテキストファイル
・-fオプション(from-encoding)に変換元符号化方式を指定
・-tオプション(to-encoding)に変換先符号化方式を指定
 

(2)nkf

■文字コード変換(自動判別)

$ nkf -s EUC.txt > out.txt

・Centos7の標準パッケージにはnkfツールは含まれておらず、EPELリポジトリからインストールが必要
・実行結果は標準出力へ出力される
・コマンド実行例の「EUC.txt」はEUC-JPで記載したテキストファイル
・指定したファイルの文字コードは自動判別されるのでコマンド指定は省略可
・出力文字コードは下記の小文字アルファベットで指定(コマンドのヘルプより)
-j  JIS コードを出力する。
-e  EUC コードを出力する。
-s  Shift_JIS コードを出力する。
-w -w8[0] -w16[BL][0] Unicode を出力する。
-w -w80 UTF8 コードを出力する。 (BOM 無し)
-w8 UTF8 コードを出力する。
-w16 -w16B0 UTF16 コードを出力する。 (Big Endian / BOM 無し)
-w16B UTF16 コードを出力する。 (Big Endian / BOM 有り)
-w16L UTF16 コードを出力する。 (Little Endian / BOM 有り)
-w16L0 UTF16 コードを出力する。 (Little Endian / BOM 無し)

■文字コード変換(変換元文字コード指定)

$ nkf -E -s EUC.txt > out.txt

※入力文字コードは下記の大文字アルファベットで指定(コマンドのヘルプより)
-J  ISO-2022-JP を仮定する。
-E  日本語 EUC (AT&T) を仮定する。
-S  Shift_JIS を仮定する。 いわゆる半角カナ (JIS X 0201 片仮名) も受け入れる。
-W  UTF-8 を仮定する。
-W8 UTF-8 を仮定する。
-W16 UTF-16 (Little Endian)を仮定する。
-W16B UTF-16 (Big Endian)を仮定する。
-W16L UTF-16 (Little Endian)を仮定する。

■文字コード判別

$ nkf -g EUC.txt

■nkfツールのインストール

$ yum install epel-release
$ yum update
$ yum install nkf