JS编码与解码

JS编码与解码

社蕙 215 2020-02-22

字符编码

在这篇文章關於字符編碼,你所需要知道的(ASCII,Unicode,Utf-8,GB2312…)中,作者很详尽地解释了字符集、字符码和相关的一些标准。可以概括总结一下:

  • 中國人民通過對 ASCII 編碼的中文擴充改造,產生了 GB2312 編碼,可以表示 6000 多個常用漢字。
  • 漢字實在是太多了,包括繁體和各種字符,於是產生了 GBK 編碼,它包括了 GB2312 中的編碼,同時擴充了很多。
  • 中國是個多民族國家,各個民族幾乎都有自己獨立的語言系統,為了表示那些字符,繼續把 GBK 編碼擴充為 GB18030 編碼。
  • 每個國家都像中國一樣,把自己的語言編碼,於是出現了各種各樣的編碼,如果你不安裝相應的編碼,就無法解釋相應編碼想表達的內容。
  • 終於,有個叫 ISO 的組織看不下去了。他們一起創造了一種編碼 UNICODE ,這種編碼非常大,大到可以容納世界上任何一個文字和標誌。所以只要電腦上有 UNICODE 這種編碼系統,無論是全球哪種文字,只需要保存文件的時候,保存成 UNICODE 編碼就可以被其他電腦正常解釋。
  • UNICODE 在網絡傳輸中,出現了兩個標準 UTF-8 和 UTF-16,分別每次傳輸 8 個位和 16 個位。於是就會有人產生疑問,UTF-8 既然能保存那麼多文字、符號,為什麼國內還有這麼多使用 GBK 等編碼的人?因為 UTF-8 等編碼體積比較大,佔電腦空間比較多,如果面向的使用人羣絕大部分都是中國人,用 GBK 等編碼也可以。

JS 编码与解码

不论是前后端,还是前端页面之间,用 URL 传参不可避免地要转换 UTF-8 编码。JS 中主要要用到两个函数:encodeURIComponentdecodeURIComponent,效果如下面的代码所示:

const origin = "字符串String001";
console.log(origin); //字符串String001
let originEn = encodeURIComponent(origin);
console.log(originEn); //%E5%AD%97%E7%AC%A6%E4%B8%B2String001
let origenDe = decodeURIComponent(originEn);
console.log(origenDe); //字符串String001

可以发现,上面的转换是不太全面的,那么在参考文章Js 中进行 utf-8 的编码和解码中,作者给出了套完全转换的 js 函数:

function encodeUtf8(text) {
  const code = encodeURIComponent(text);
  const bytes = [];
  for (var i = 0; i < code.length; i++) {
    const c = code.charAt(i);
    if (c === "%") {
      const hex = code.charAt(i + 1) + code.charAt(i + 2);
      const hexVal = parseInt(hex, 16);
      bytes.push(hexVal);
      i += 2;
    } else bytes.push(c.charCodeAt(0));
  }
  return bytes;
}
function decodeUtf8(bytes) {
  var encoded = "";
  for (var i = 0; i < bytes.length; i++) {
    encoded += "%" + bytes[i].toString(16);
  }
  return decodeURIComponent(encoded);
}

下面是使用示例:

var array = encodeUtf8("字符串String001");
console.log(array); //(18) [229, 173, 151, 231, 172, 166, 228, 184, 178, 83, 116, 114, 105, 110, 103, 48, 48, 49]
var content = decodeUtf8(array);
console.log(content); //字符串String001