JavaScript中的UTF-16到UTF-8转换

9
我有一些以UTF-16编码的Base64数据,我试图解码这些数据,但大多数库只支持UTF-8。我认为我必须去掉空字节,但我不确定如何去掉。
目前,我正在使用David Chambbers Polyfill进行Base64编码,但我也尝试过其他库,例如phpjs.org,但它们都不支持UTF-16。
需要指出的一件事是,在Chrome上,atob方法可以正常工作,而在Firefox上,我得到了描述here的结果,在IE中,我只返回了第一个字符。
非常感谢任何帮助。

2
我有点困惑你想做什么。你有Base64数据,但它是UTF-16的?我不确定,但我有一种预感,你可以只剪掉每两个字节,留下你需要的内容。 - Brad
1
可以使用PHP轻松进行转换:http://php.net/manual/zh/function.mb-convert-encoding.php - sdespont
2
@sdespont,PHP和JavaScript有什么关系?... - Brad
1
@JanDvorak,我知道你的意思,但是有很多原因为什么你可能想在JavaScript中这样做。 - Brad
2
@Brad 我猜它是base64编码的UTF-16(可以包含任何文本),而不是UTF-16编码的base64(这将有点浪费)。 - John Dvorak
显示剩余9条评论
1个回答

27

你想解码UTF-16,而不是转换为UTF-8。解码意味着结果是一串抽象字符的字符串。当然,字符串也有内部编码,如JavaScript中的UTF-16或UCS-2,但那只是实现细节。

对于字符串来说,目标是让你不必担心编码,只需关注“它们本身”的字符操作。因此,你可以编写不需要完全解码输入的字符串方法。当然,在许多边缘情况下,这种方法会失效。

你不能仅通过删除null值解码utf-16。我的意思是,这将在unicode的前256个代码点中正常工作,但是当使用unicode中的其他110,000个字符中的任何一个时,你会得到垃圾结果。你甚至无法使最流行的非ASCII字符(如em dash或任何智能引号)起作用。

此外,从你的示例来看,它看起来像是UTF-16LE。

//Braindead decoder that assumes fully valid input
function decodeUTF16LE( binaryStr ) {
    var cp = [];
    for( var i = 0; i < binaryStr.length; i+=2) {
        cp.push( 
             binaryStr.charCodeAt(i) |
            ( binaryStr.charCodeAt(i+1) << 8 )
        );
    }

    return String.fromCharCode.apply( String, cp );
}

var base64decode = atob; //In chrome and firefox, atob is a native method available for base64 decoding

var base64 = "VABlAHMAdABpAG4AZwA";
var binaryStr = base64decode(base64);
var result = decodeUTF16LE(binaryStr);

现在您甚至可以让智能引号正常工作:

var base64 = "HCBoAGUAbABsAG8AHSA="
var binaryStr = base64decode(base64);
var result = decodeUTF16LE(binaryStr);
//"“hello”"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接