各种转成buffer,各种锟斤拷。。。。
原因就在于【百度一下午了】,用 google 就好了
@alsotang 别抖机灵了,国外有用gb2312吗?
@captainblue2013 递 iconv-lite
@xadillax 试过了,官方给的是string->buffer,或者buffer->string,此处有个疑问。
你是解决导出文件时候乱码还是。。
@wewoor 不是文件,就是字符串
utf8转gb2312,必须查对照表,用 iconv-lite 是正道,“锟斤拷” 是你不会用。。。
https://github.com/XadillaX/spidex/blob/v2/lib/spidex.js#L177
/* GBK_USC2_TABLE : GBK 与 USC2 对照表来自: https://github.com/ashtuchkin/iconv-lite 感谢iconv-lite作者*/ //GBK_USC2_TABLE很长。。。请自己补全 var GBK_USC2_TABLE={33088:19970,33089:19972,33090:19973,33091:19974,......}; // 上面表的反转表, 即 usc2 -> gkb var UCS2_GBK_TABLE = {}; for(var k in GBK_USC2_TABLE) { UCS2_GBK_TABLE[ GBK_USC2_TABLE[k] ] = k; } function __EmptyStr(str) { if(typeof(str)=='undefined') return ''; if(str==null) return ''; return ''+str.toString(); } function utf8_to_gbk(utf8_buffer) { if(!Buffer.isBuffer(utf8_buffer) || utf8_buffer.length<=0) return new Buffer(0); return str_to_gbk( utf8_buffer.toString('utf8') ); } function str_to_gbk(str) { var s = __EmptyStr(str); var b = new Buffer(s.length * 2); // s.length 是串的字符个数,不是字节数, // 所以,即使全部是汉字,转gbk后最大就是2倍长度 var k = 0; for(var i=0; i<s.length; i++) { var c = s.charCodeAt(i); //console.log(c); if(c<=0xFF) { // 单字节 b[k++] = c; continue; } if(c in UCS2_GBK_TABLE) { // 合法的GBK编码,转成两个字节 c = UCS2_GBK_TABLE[c]; b[k++] = c >> 8; // first b[k++] = c & 0xFF; // second continue; } // 非法的GBK编码,用两个问号代替 b[k++] = 0x3F; // 0x3F = ? b[k++] = 0x3F; // 0x3F = ? } return b.slice(0, k); // 返回实际长度的buffer } function gbk_to_utf8(gbk_buffer){ if(!Buffer.isBuffer(gbk_buffer) || gbk_buffer.length<=0) return new Buffer(0); var n = gbk_buffer.length; var b = new Buffer(n * 2); // s.length 是gbk字节数, // 所以,即使全部是非汉字,转ucs2后最大就是2倍长度 var k = 0; for(var i=0; i < n; i++) { var c = gbk_buffer[i]; if(i+1<n) { // gbk 编码规范: // 第一字节的范围是81–FE, 不含两头 80 和 FF // 第二字节的范围是40–FE,但是去掉中间的 7F if(0x81<=c && c<=0xFE) { // && 0x40<=c2 && c2<=0xFE && c2!=0x7F) { var cu = c * 256 + gbk_buffer[i+1]; if(cu in GBK_USC2_TABLE) { // 找到对应的 ucs2 编码 c = GBK_USC2_TABLE[cu]; i++; // 重要,表示本次处理了 2 个字节 } } } // 现在的 c 可能是单字节,也可能是ucs2编码,根据 ucs2->utf8的规则来转换 if(c <= 0x007F) b[k++] = c & 0xFF; else { if(c <= 0x07FF) { b[ k++ ] = 0xC0 + ( c >> 6); // 1100 0000 + c >> 6 b[ k++ ] = 0x80 + ( c & 0x003F); // 1000 0000 + c & 0011 1111 } else { b[ k++ ] = 0xE0 + ( c >> 12); // 1110 0000 + c >> 12 b[ k++ ] = 0x80 + ((c >> 6) & 0x003F); // 1000 0000 + c >> 6 & 0011 1111 b[ k++ ] = 0x80 + ( c & 0x003F); // 1000 0000 + c & 0011 1111 } } } return b.slice(0, k); // b 现在是 utf8 编码了~ console.log(b); } function gbk_to_str(gbk_buffer) { return gbk_to_utf8(gbk_buffer).toString('utf8'); } function ucs2_to_gbk(usc2_buffer) { if(!Buffer.isBuffer(usc2_buffer) || usc2_buffer.length<=0) return null; var s = usc2_buffer.toString('usc2'); var b = new Buffer(s.length * 2); // s.length 是串的字符个数,不是字节数, // 所以,即使全部是汉字,转gbk后最大就是2倍长度 var k = 0; for(var i=0; i<s.length; i++) { var c = s.charCodeAt(i); //console.log(c); if(c<=0xFF) { // 单字节 b[k++] = c; continue; } if(c in UCS2_GBK_TABLE) { // 合法的GBK编码,转成两个字节 c = UCS2_GBK_TABLE[c]; b[k++] = c >> 8; // first b[k++] = c & 0xFF; // second continue; } // 非法的GBK编码,用两个问号代替 b[k++] = 0x3F; // 0x3F = ? b[k++] = 0x3F; // 0x3F = ? } return b.slice(0, k); // 返回实际长度的buffer } function gbk_to_ucs2(gbk_buffer) { if(!Buffer.isBuffer(gbk_buffer) || gbk_buffer.length<=0) return null; var n = gbk_buffer.length; var b = new Buffer(n * 2); // s.length 是gbk字节数, // 所以,即使全部是非汉字,转ucs2后最大就是2倍长度 var k = 0; for(var i=0; i < n; i++) { var c = gbk_buffer[i]; if(i+1<n) { // gbk 编码规范: // 第一字节的范围是81–FE, 不含两头 80 和 FF // 第二字节的范围是40–FE,但是去掉中间的 7F if(0x81<=c && c<=0xFE) { // && 0x40<=c2 && c2<=0xFE && c2!=0x7F) { var cu = c * 256 + gbk_buffer[i+1]; if(cu in GBK_USC2_TABLE) { // 找到对应的 ucs2 编码 c = GBK_USC2_TABLE[cu]; i++; // 重要,表示本次处理了 2 个字节 } } } // 现在的 c 可能是单字节,也可能是ucs2编码 b[k++] = c & 0xFF; b[k++] = c >> 8; } return b.slice(0, k); // b 现在是 ucs2 编码了~ console.log(b); } // exports 的函数 module.exports.UTF8_TO_GBK_bb = utf8_to_gbk; // buffer到buffer module.exports.UCS2_TO_GBK_bb = ucs2_to_gbk; // buffer到buffer module.exports.GBK_TO_UTF8_bb = gbk_to_utf8; // buffer到buffer module.exports.GBK_TO_UCS2_bb = gbk_to_ucs2; // buffer到buffer module.exports.UTF8_TO_GBK_sb = str_to_gbk; // string到buffer module.exports.GBK_TO_UTF8_bs = gbk_to_str; // buffer到string // 测试... // // var s = '\u00FE a盘1苙2苘&暻-鎔-# \u82DA'; // console.log(s); // // var b = new Buffer(s, 'utf8'); // console.log('utf8 buffer = ', b ); // // var cb1 = new Buffer(s, 'ucs2'); // console.log('ucs2 buffer = ', cb1 ); // console.log(cb1.toString('ucs2')); // // var gb = utf8_to_gbk(b); // console.log('gbk buffer = ', gb ); // //console.log( gb.toString('binary') ); // // var ub = gbk_to_utf8(gb); // console.log('utf8 buffer = ', ub ); // console.log(ub.toString('utf8')); // // var ub2 = gbk_to_ucs2(gb); // console.log('ucs2 buffer = ', ub2 ); // console.log(ub2.toString('ucs2'));
CNode 社区为国内最专业的 Node.js 开源技术社区,致力于 Node.js 的技术研究。
原因就在于【百度一下午了】,用 google 就好了
原因就在于【百度一下午了】,用 google 就好了
@alsotang 别抖机灵了,国外有用gb2312吗?
@captainblue2013 递 iconv-lite
@xadillax 试过了,官方给的是string->buffer,或者buffer->string,此处有个疑问。
你是解决导出文件时候乱码还是。。
@wewoor 不是文件,就是字符串
utf8转gb2312,必须查对照表,用 iconv-lite 是正道,“锟斤拷” 是你不会用。。。
https://github.com/XadillaX/spidex/blob/v2/lib/spidex.js#L177