zoukankan      html  css  js  c++  java
  • JS 转 gbk 编码与 iconv-lite 探究

    直接使用 api

    const urlencode = require('urlencode');
    
    const text = '你好';
    
    urlencode.encode(text, 'gbk').toLocaleLowerCase();
    // '%c4%e3%ba%c3'
    
    urlencode.decode('%c4%e3%ba%c3', 'gbk')
    // 你好
    

    这个 urlencode 的库是使用了 iconv-lite 的,其 encode 方法摘录出来看是这样的

    var iconv = require('iconv-lite');
    function encode(str, charset) {
      if (isUTF8(charset)) {
        return encodeURIComponent(str);
      }
        
      // 使用 iconv 转为 buffer
      var buf = iconv.encode(str, charset);
      var encodeStr = '';
      var ch = '';
      for (var i = 0; i < buf.length; i++) {
        // 从 buffer 里按 16 进制拿出每个字节
        ch = buf[i].toString('16');
        if (ch.length === 1) {
          ch = '0' + ch;
        }
        // 拼接百分号
        encodeStr += '%' + ch;
      }
      encodeStr = encodeStr.toUpperCase();
      return encodeStr;
    }
    

    iconv-lite 可以把字符转成 gbk 的 buffer ,但转成 gbk 形式的 string 是没有的。这是因为,node 内部也不支持直接操作 GBK 字符串,瞧 Buffer.from(string[, encoding]) 第二个参数里就无 gbk。

    补充 gbk 编码说明

    '你'.charCodeAt(0) // 20320
    
    let iconv = require('iconv-lite');
    
    let buff = iconv.encode('你', 'GBK');
    
    console.log(buff)
    // Buffer(3) [196, 227]
    

    为什么 Buffer 对象里的十进制数字是 196 和 227?

    参见 GBK 编码大全,GBK 编码中“你字”

    C4 0 1 2 3 4 5 6 7 8 9 A B C D E F
    A   摹 蘑 模 膜 磨 摩 魔 抹 末 莫 墨 默 沫 漠 寞
    B 陌 谋 牟 某 拇 牡 亩 姆 母 墓 暮 幕 募 慕 木 目
    C 睦 牧 穆 拿 哪 呐 钠 那 娜 纳 氖 乃 奶 耐 奈 南
    D 男 难 囊 挠 脑 恼 闹 淖 呢 馁 内 嫩 能 妮 霓 倪
    E 泥 尼 拟 你 匿 腻 逆 溺 蔫 拈 年 碾 撵 捻 念 娘
    F 酿 鸟 尿 捏 聂 孽 啮 镊 镍 涅 您 柠 狞 凝 宁
    

    所以 “你” 这个字的高位是 0xC4 也就是十进制的 196,而低位是 0xE3 也就是十进制 227,“好” 这个字也同理。

    补充说明:GBK 使用两个字节进行表示,每个字节的第一位均为1,这样在高位字节和低位字节的值均大于127。

    规定:但两个大于127的字符连在一起时,就表示一个汉字,前面的一个字节(称之为高字节)从0xA1用到 0xF7,后面一个字节(低字节)从0xA1到0xFE,这样可以组合出大约 7000 多个简体汉字了。

    在这些编码里,数学符号、罗马希腊的字母、日文的假名们都被编进去了,连在 ASCII 里本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这就是常说的”全角”字符,而原来在 127 号以下的那些就叫”半角”字符了。

    那 iconv-lite 是这么做到转 gbk 编码的?

    此库内部建了一个从 utf-8 映射去 gbk 编码的 map 表。

    奥秘在于在 dbsc-data.js 里有一段

    'gbk': {
      type: '_dbcs',
      table: function() { return require('./tables/cp936.json').concat(require('./tables/gbk-added.json')) },
    },
    

    所以 gbk 的映射编码来自于两个 json 文件,cp936.json 与 gbk-added.json。

  • 相关阅读:
    jdk9以上配置远程断点调试debug
    记解决grpc报错:HTTP/2 client preface string missing or corrupt. Hex dump for received bytes
    CENTOS7静默安装ORACLE11G及数据泵迁移
    数据链路层(7) 链路层设备
    数据链路层(6) 局域网 无线局域网 广域网
    数据链路层(5) 动态分配信道 ALOHA协议、CSMA协议、CSMA/CD协议、CSMA/CA
    数据链路层(3) 流量控制
    数据链路层(2) 差错控制
    数据链路层(1) 数据链路层基本概念
    数据链路层(4) 静态划分信道
  • 原文地址:https://www.cnblogs.com/everlose/p/13189096.html
Copyright © 2011-2022 走看看