ホーム > カテゴリ > HTML5・JavaScript >

文字列をUTF8からShift-JISに変換する際の「円記号/バックスラッシュ」に対応する[encoding.js]

JavaScriptでencoding.jsを使用して文字列をUnicodeのUTF8からShift-JIS(SJIS)へ変換する際に「円記号」(バックスラッシュ)は「?」に変換されてしまいます。今回はencoding.jsを修正して「円記号」に対応する方法をご紹介します。

UTF8からSJISへ変換する

JavaScriptで文字コードを変換するにはオープンソースの「encoding.js」を利用している方が多いかも知れません。

https://github.com/polygonplanet/encoding.js

ただ、コード変換のテーブルが「べた書き」なのでファイルのサイズが大きいのが難点です。そのうち、軽量版が公開されるかも知れません。

円記号/バックスラッシュ

Windowsや日本語フォントなどでは「バックスラッシュ」の文字コードを「円記号」として表示している場合が多いです。文字コードの詳細は次のようになります。

記号UnicodeUTF8Shift-JIS(SJIS)
円記号¥U+00A50xC2A5存在しない
バックスラッシュ\U+005C0x005C0x005C

キーボードで「¥」記号を押すと「0x005C」となります。パソコン黎明期に日本としては「¥」が必要でしたので、半ば強引に「\」を「¥」にしたんでしょうね^^;

本題ですが、この表を見て頂くとお分かりになると思いますが、Unicode/UTF8の「¥」記号をShift-JISに変換する事はできません。何故ならば、「¥」記号の文字コードはShift-JISには存在しないからです。

ですので、「encoding.js」でUTF8の「¥」をSJISへ変換すると「?」になります。

HTMLで「¥」を表示させるには「¥」と記述します。「\」を表示させるにはフォントに「Arial」系を指定します。

encoding.jsの変更

UTF8からSJISへ変換する際に「¥」を対応させるにはUTF8ToSJIS()の関数を次のように変更します。

function UTF8ToSJIS(data) {
  var results = [];
  var i = 0;
  var len = data && data.length;
  var b, b1, b2, utf8, jis;

  for (; i < len; i++) {
    b = data[i];
    if (b >= 0x80) {
      if (b <= 0xDF) {
        // 2 bytes.
        utf8 = (b << 8) + data[++i];
      } else {
        // 3 bytes.
        utf8 = (b << 16) +
               (data[++i] << 8) +
               (data[++i] & 0xFF);
      }

      jis = UTF8_TO_JIS_TABLE[utf8];
      if (jis === void 0) {
        
         //  *** 変更の開始
         
           //  UTF8の円記号(\)をSJISのバックスラッシュ(表記上は\)に変換 
           if(utf8 == 0xC2A5){
             results[results.length] = 0x5C;
           }else{
             results[results.length] = UTF8_UNKNOWN;
           }
         
         //  *** 変更の終了
         
         // 元のコード        
         //results[results.length] = UTF8_UNKNOWN;
      } else {
        if (jis < 0xFF) {
          results[results.length] = jis + 0x80;
        } else {
          if (jis > 0x10000) {
            jis -= 0x10000;
          }

          b1 = jis >> 8;
          b2 = jis & 0xFF;
          if (b1 & 0x01) {
            b1 >>= 1;
            if (b1 < 0x2F) {
              b1 += 0x71;
            } else {
              b1 -= 0x4F;
            }

            if (b2 > 0x5F) {
              b2 += 0x20;
            } else {
              b2 += 0x1F;
            }
          } else {
            b1 >>= 1;
            if (b1 <= 0x2F) {
              b1 += 0x70;
            } else {
              b1 -= 0x50;
            }
            b2 += 0x7E;
          }
          results[results.length] = b1 & 0xFF;
          results[results.length] = b2 & 0xFF;
        }
      }
    } else {
      results[results.length] = data[i] & 0xFF;
    }
  }
  return results;
}

変更箇所は23行目から32行目です。UTF8の円記号(¥ - 0xC2A5)をSJISのバックスラッシュ(表記上は¥ - 0x5C)に変換しているだけです。

encoding.jsのソースコードはあんまり読み込んでいないので、もっと良い手法があるかも知れません。

※この記事を作成した時点のencoding.jsのバージョンは「1.0.24」です。





関連記事



公開日:2016年05月31日
記事NO:01990