前言

昨天寒风在用node-webkit写一个小应用的时候,发现这样一个问题,nodejs的utility对页面用户输入的中文进行md5、sha1加密和base64编码解码时结果不对。

在确认用户输入无误且左右空格都去除的情况下,怀疑是编码问题。但查看文件和页面配置都是utf8的编码,于是有点没有头绪,但还是觉得是编码方面的问题,因为英文是正确的。

解答

一直以来,对编码方面的东西了解不是很深入,后面谷歌了很久,网上说javascript对中文的处理是utf16,而不是utf8,这个有点意外,于是找到这两个函数:utf16to8,utf16to8。

将用户输入这样处理:

var input = utf16to8($('#decode-input').val());

然后用utility进行md5加密:

utility.md5(input);

结果还是不对,alert(input),发现是无法正常显示中文的。于是改成:

var input = utf8to16(utf16to8($('#decode-input').val()));

困惑

结果正常了!问题虽然解决,但仍然想不明白,既然js内部中文处理是utf16,那么为什么先转为utf8再转为utf16就行了呢?不知是否有高人能否帮解答一下。

解药

最后,附utf16to8和utf8to16函数:

function utf16to8(str) {
    var out, i, len, c;

    out = "";
    len = str.length;
    for(i = 0; i < len; i++) {
    c = str.charCodeAt(i);
    if ((c >= 0x0001) && (c <= 0x007F)) {
        out += str.charAt(i);
    } else if (c > 0x07FF) {
        out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
        out += String.fromCharCode(0x80 | ((c >>  6) & 0x3F));
        out += String.fromCharCode(0x80 | ((c >>  0) & 0x3F));
    } else {
        out += String.fromCharCode(0xC0 | ((c >>  6) & 0x1F));
        out += String.fromCharCode(0x80 | ((c >>  0) & 0x3F));
    }
    }
    return out;
}

function utf8to16(str) {
    var out, i, len, c;
    var char2, char3;

    out = "";
    len = str.length;
    i = 0;
    while(i < len) {
    c = str.charCodeAt(i++);
    switch(c >> 4)
    { 
      case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
        // 0xxxxxxx
        out += str.charAt(i-1);
        break;
      case 12: case 13:
        // 110x xxxx   10xx xxxx
        char2 = str.charCodeAt(i++);
        out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
        break;
      case 14:
        // 1110 xxxx  10xx xxxx  10xx xxxx
        char2 = str.charCodeAt(i++);
        char3 = str.charCodeAt(i++);
        out += String.fromCharCode(((c & 0x0F) << 12) |
                       ((char2 & 0x3F) << 6) |
                       ((char3 & 0x3F) << 0));
        break;
    }
    }

    return out;
}

如果您觉得您在我这里学到了新姿势,博主支持转载,姿势本身就是用来相互学习的。同时,本站文章如未注明均为 hisune 原创 请尊重劳动成果 转载请注明 转自: nodejs中md5,sha1,base64编码中文不对的问题 - hisune.com