今回は元ネタにプログラムが掲載されていません。ですが、せっかくなので当サイトではプログラムを掲載することにしましょう。
シフトJIS⇔JIS変換
本来であれば、シフトJISからまずは区点番号に変換して、区点番号からJISコードやEUC-JPに変換するのが自然です。しかし、区点番号を直接利用する機会はほとんどないので、今回は直接JISコードに変換することにします。JISコードを使う機会も最近はほとんどありませんが、とりあえず進めます。
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
constexpr unsigned short sjis_to_jis(unsigned short sjis) { int h = sjis >> 8; int l = sjis & 0xff; if (h <= 0x9f) { if (l < 0x9f) h = (h << 1) - 0xe1; else h = (h << 1) - 0xe0; } else { if (l < 0x9f) h = (h << 1) - 0x161; else h = (h << 1) - 0x160; } if (l < 0x7f) l -= 0x1f; else if (l < 0x9f) l -= 0x20; else l -= 0x7e; return h << 8 | l; } |
この関数では、シフトJISを16ビットの値として受け取って、JISコードを16ビットの値として返します。
次は先ほどの逆で、JISコードからシフトJISに変換します。
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
constexpr unsigned short jis_to_sjis(unsigned short jis) { int h = jis >> 8; int l = jis & 0xff; if (h & 1) { if (l < 0x60) l += 0x1f; else l += 0x20; } else { l += 0x7e; } if (h < 0x5f) h = (h + 0xe1) >> 1; else h = (h + 0x161) >> 1; return h << 8 | l; } |
今回は、C++11以降で定数式を得られるようにconstexprを付けました。C++03までの場合はコンパイルできなくなるのでconstexprは取り除いてください。
JIS⇔区点番号変換
JISコードから区点番号にするのは簡単です。上位下位それぞれから0x20を引けば区点番号になります。例えば、全角空白のJISコードは0x2121ですから、区点番号は0x0101になります。
0 1 2 3 4 5 |
constexpr unsigned short jis_to_kuten(unsigned short jis) { return jis - 0x2020; } |
今度は先ほどの逆で、区点番号からJISコードに変換します。上位下位それぞれに0x20を足してあげればOKです。
0 1 2 3 4 5 |
constexpr unsigned short kuten_to_jis(unsigned short kuten) { return kuten + 0x2020; } |
シフトJISと区点番号の相互変換の関数は実装しませんので、必要であれば、これまでの関数を組み合わせればよいでしょう。
JIS⇔EUC-JP変換
JISコードからEUC-JPへの変換も簡単です。JISコードの上位下位それぞれに0x80を足してあげればEUC-JPになります。JISコードの全角空白は0x2121でしたので、EUC-JPでは0xa1a1になります、
0 1 2 3 4 5 |
constexpr unsigned short jis_to_eucjp(unsigned short jis) { return jis + 0x8080; } |
EUC-JPからJISコードに変換する場合は、上位下位それぞれから0x80を引いてあげればOKです。
0 1 2 3 4 5 |
constexpr unsigned short eucjp_to_jis(unsigned short kuten) { return kuten - 0x8080; } |
昔はLinuxも含めたUnixの環境ではEUC-JPが使われていたのですが、最近はすっかり見なくなってしまいました。UTF-16に比べると日本語を表すのに必要なバイト数が少ないですし、シフトJISのようないわゆる「ダメ文字」もないので使い勝手は悪くないんですけどね。
ところで、EUC-JPは半角かなを表現することもできます。また、第3、第4水準の漢字を表現することもできます(3バイト必要になります)。ただ、今回はそこまで対応するのはやめておきます。
なお、シフトJISとEUC-JPの相互変換の関数も実装しませんので、必要であれば、これまでの関数を組み合わせればよいでしょう。