各种转成buffer,各种锟斤拷。。。。
10 回复
/* 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'));