LANG SELRCT

コードを書く場所についてはこちら

2018年2月5日月曜日

文字列⇔UTF16⇔16進数の相互変換をする(サロゲートペア対応)


文字列とUTF16と16進数について調べているときに作った相互変換機能です

いずれかの入力欄に変換したい値を入れると他の2つの値が自動で表示されます




例:
文字列に「𠮟」と入力するか
UTF16の1つめに「55362」2つめに「57247」と入力するか
16進数の1つめに「d842」2つめに「df9f」と入力すると
以下のように他の値が自動で埋まる
※ 𠮟 は常用漢字の中で唯一のサロゲートペア
サロゲートペア非対応はこちら


HTML Serviceで作ってみる



コード.gs
function doGet() {
  return HtmlService.createHtmlOutputFromFile("index");
}
意訳
この機能がやること
指定したHTMLファイルを表示する




index.html
<!DOCTYPE html>
<html>
<body>
  <table>
    <tbody>
      <tr>
        <td>
          <label>文字列</label>
        </td>
        <td>
          <input type="text" id="str">
        </td>
      </tr>
      <tr>
        <td>
          <label>UTF16</label>
        </td>
        <td>
          <input type="text" id="utf16_1">
        </td>
        <td>
          <input type="text" id="utf16_2">
        </td>
      </tr>
      <tr>
        <td>
          <label>16進数</label>
        </td>
        <td>
          <input type="text" id="hexadecimal_1">
        </td>
        <td>
          <input type="text" id="hexadecimal_2">
        </td>
      </tr>
    </tbody>
  </table>
  <script>
    var str = document.getElementById("str");
    var utf16_1 = document.getElementById("utf16_1");
    var utf16_2 = document.getElementById("utf16_2");
    var hexadecimal_1 = document.getElementById("hexadecimal_1");
    var hexadecimal_2 = document.getElementById("hexadecimal_2");

    str.onkeyup = keyup;
    utf16_1.onkeyup = keyup;
    utf16_2.onkeyup = keyup;
    hexadecimal_1.onkeyup = keyup;
    hexadecimal_2.onkeyup = keyup;

    function keyup() {
      switch (this.id) {
      case "str":
        get_utf16();
        get_hexadecimal();
        break;
      case "utf16_1":
      case "utf16_2":
        get_hexadecimal();
        get_str();
        break;
      case "hexadecimal_1":
      case "hexadecimal_2":
        get_str();
        get_utf16();
        break;
      }
    }

    function get_str() {
      if (hexadecimal_2.value == "") {
        str.value = String.fromCharCode("0x" + hexadecimal_1.value);
      } else {
        str.value = String.fromCharCode("0x" + hexadecimal_1.value) + String.fromCharCode("0x" + hexadecimal_2.value);
      }
    }

    function get_utf16() {
      if (str.value.length == 2) {
        utf16_1.value = str.value.charCodeAt(0);
        utf16_2.value = str.value.charCodeAt(1);
      } else {
        utf16_1.value = str.value.charCodeAt(0);
        utf16_2.value = "";
      }
    }

    function get_hexadecimal() {
      if (utf16_2.value == "") {
        hexadecimal_1.value = parseInt(utf16_1.value).toString(16);
        hexadecimal_2.value = "";
      } else {
        hexadecimal_1.value = parseInt(utf16_1.value).toString(16);
        hexadecimal_2.value = parseInt(utf16_2.value).toString(16);
      }
    }
  </script>
</body>
</html>
意訳
これはHTML5文書です






文字列のラベル


そのテキストボックス




UTF16のラベル


utf16_1のテキストボックス


utf16_2のテキストボックス




16進数のラベル


hexadecimal_1のテキストボックス


hexadecimal_2のテキストボックス





idがstrの要素を取得する
idがutf16_1の要素を取得する
idがutf16_2の要素を取得する
idがhexadecimal_1の要素を取得する
idがhexadecimal_2の要素を取得する

idがstrの要素でキーが上がったらkeyupを実行する
idがutf16_1の要素でキーが上がったらkeyupを実行する
idがutf16_2の要素でキーが上がったらkeyupを実行する
idがhexadecimal_1の要素でキーが上がったらkeyupを実行する
idがhexadecimal_2の要素でキーが上がったらkeyupを実行する

この機能がやること
idによって処理を分ける
idがstrなら
get_utf16()と
get_hexadecimal()を実行する

idがutf16_1の場合
idがutf16_2の場合
get_hexadecimal()と
get_str()を実行する

idがhexadecimal_1の場合
idがhexadecimal_2の場合
get_str()と
get_utf16()を実行する




この機能がやること
もしhexadecimal_2の値が空なら
strの値はhexadecimal_1の頭に0xを付けて文字列にした値を入れる
空じゃなければ
strの値はhexadecimal_1の頭に0xを付けて文字列にした値とhexadecimal_2の頭に0xを付けて文字列にした値を足して入れる


この機能がやること
もしstrの値が2なら(サロゲートペアなら)
utf16_1の値はstrの値の前半をUTF16にした値を入れる
utf16_2の値はstrの値の後半をUTF16にした値を入れる
それ以外なら
utf16_1の値はstrの値をUTF16にした値を入れる
utf16_2の値は空にする



この機能がやること
もしutf16_2の値が空なら(サロゲートペアじゃないなら)
hexadecimal_1の値はutf16_1の値を16進数にした値を入れる
hexadecimal_2の値は空にする
サロゲートペアなら
hexadecimal_1の値はutf16_1の値を16進数にした値を入れる
hexadecimal_2の値はutf16_2の値を16進数にした値を入れる