読者です 読者をやめる 読者になる 読者になる

ぺーぺーSEのブログ

備忘録・メモ用サイト。

Javaで文字コードを扱ってみる

自分なりの簡単な解釈とまとめ。
文字コードは以下の2つにわけて理解するとよい気がする。

  • 文字集合
    • 文字には集合がある。例えば、英語はアルファベット、日本語はひらがな・カタカナ・漢字、ドイツ語はなんだろう。。。など。
    • バイト表現とか関係なく、文字実体そのもの(「a」とか「あ」とか「伊」とか)を複数グループとしてまとめたものが文字集合
    • 例えば下記のようなものがある。
  • 符号化方式
    • コンピュータ上で文字を利用するために各文字に割り当てられるバイト表現。「あ」をJISでエンコーディング(ある文字をある符号化方式でバイト表現化すること)すると「0x2242」、SJISだと「0x82A0」、EUCだと「0xA4A2」と表現される。(※「0x」は16進数の意)
    • 文字によって1バイトで表現できるもの、2バイト、それ以上がある。
    • エンコーディングの種類には下記のようなものがある。同じ文字でもそれぞれのエンコーディング方法によってバイト表現が変わってくる。
    • 符号化方式によって、バイト表現できる対象の文字集合も変わってくる。例えば、UTF-8エンコーディングできるが、SJISではできない文字がある。
    • ASCII(アルファベット、数字、半角の記号)については、どの符号化方式でもバイト表現は同じ(?)のようである。だから文字化けしない(ように見える)。

下記に「Shift_JIS」でエンコーディング可能かどうか判定して文字コードチェックするJavaのサンプルコードを書いてみる。
Shift_JIS」でエンコード可能ということは、文字集合JIS X 0201」、「JIS X 0208」と一部の制御コード(?)に含まれるということになる。
(「円マーク(\)」と「バックスラッシュ(/)」が差し替わってるとかあるかも。。。)

public class HogeUtils {

  public static boolean checkShiftJis(String str) throws UnsupportedEncodingException {

    if (str == null || str.length == 0) {
      return false;
    }

    // Javaは内部で文字をUnicodeで扱っているため、全ての文字を扱うことができる(?)。
    // 入力文字列を"Shift_JIS"で符号化し、符号化配列を"Shift_JIS"で表現されたバイト配列として文字へデコードする。
    // もし、入力文字列が"Shift_JIS"で表現できない文字を含むと元の文字列へ戻らない。
    String encodingStr = new String(str.getBytes("Shift_JIS"), "Shift_JIS");

    // 上記変換結果と元の文字列が同じかどうかを比較する。
    // 同じ出ない場合、"Shift_JIS"で表現できない文字である。
    // つまり、「JIS X 0201」、「JIS X 0208」と一部の制御コード(?)に含まれない文字だったことになる。
    if (str == null ? encodingStr == null : str.equals(encodingStr)) {
      return false;
    }

    // 半角カナ文字が含まれていたら嫌な場合は下記を追加。
    // 「\uFF61」〜「\uFF9F」の範囲はUnicodeで半角カナの範囲。
    // 正規表現で上記の範囲のパターンにマッチしたら半角カナが含まれると判断するロジック。
    Pattern kanaPattern = Pattern.compile("[\uFF61-\uFF9F]");
    if (kanaPattern.matcher(str).find()) {
      return false;
    }

  }

}


参考
http://d.hatena.ne.jp/kanonji/20120502/1335964300