我该如何在Javascript中对数据(而不是字符串)进行Base64编码?

5

我正在将一项功能从Objective-C iPhone应用程序移植到Javascript iPhone应用程序(Appcelerator Titanium)。在Objective-C中,我有一个NSData对象,代表这个令牌:

//NSData object printed to the console:
<0cd9f571 b0e66e6d ca410d12 f67a404a 7e64b9b5 d2483fd9 63a9267b 1c7609e2>

这不是一个字符串,而是一个NSData对象——一个字节缓冲区的面向对象封装。当我对该对象进行base64编码时,得到以下结果:

//base64 encoded NSData object
DNn1cbDmbm3KQQ0S9npASn5kubXSSD/ZY6kmexx2CeI=

在我的JavaScript实现中,我有同一个标记的字符串表示。它看起来像这样:
//string version of the token in my javascript implementation
0cd9f571b0e66e6dca410d12f67a404a7e64b9b5d2483fd963a9267b1c7609e2

当我在javascript中对字符串对象进行base64编码时,得到以下结果:
//base64 encoded token (string) in javascript
MGNkOWY1NzFiMGU2NmU2ZGNhNDEwZDEyZjY3YTQwNGE3ZTY0YjliNWQyNDgzZmQ5NjNhOTI2N2IxYzc2MDllMg==

问题是,我要发布到的Web服务不想要base64编码的字符串,它想要base64编码的数据!我该如何在JavaScript中实现这个功能?

看起来0cd9f571b0e66e6dca410d12f67a404a7e64b9b5d2483fd963a9267b1c7609e2已经是base64编码了,不是吗? - TheBrain
@TheBrain:这是一个十六进制数。换句话说,它是基于16进制编码的。 - outis
3个回答

3

在将十六进制字符串进行 base64 编码之前,先进行转换应该可以解决此问题。在 JavaScript 中可通过以下方式实现:

if (! Array.prototype.map) {
    Array.prototype.map = function(f) {
        var result = [];
        for (var i=0; i < this.length; ++i) {
            result[i] = f(this[i], i);
        }
        return result;
    }
}
String.prototype.b16decode = function() {
    return this.match(/../g).map(
        function (x) {
            return String.fromCharCode(parseInt(x, 16));
        }
    ).join('');
}

例如,执行
btoa('0cd9f571b0e66e6dca410d12f67a404a7e64b9b5d2483fd963a9267b1c7609e2'.b16decode())

(其中btoa是浏览器提供的base64编码函数)会导致以下结果:

"DNn1cbDmbm3KQQ0S9npASn5kubXSSD/ZY6kmexx2CeI="

0

你需要将原始的十六进制字符串读取为整数列表。请参考如何在JavaScript中将十进制转换为十六进制?

然后,您需要修改其中一个许多base64 js算法,以使用整数而不是charCodeAt。请参考http://www.webtoolkit.info/javascript-base64.html 还可以参考http://www.codeproject.com/KB/cs/base64encoder.aspx,这是一种直接将整数转换为base64算法(大多数是字节或字符串到base64)。

即使最后一个示例是C#,您也应该能够将其转换为JS。

如果我以后有时间,我会看看是否可以编写代码。


修改base64编码器并不是必要的。可以使用parseInt(_, 16)将十六进制字符串转换为包含二进制数据的字符串,然后将其传递给base64编码器。通过适当的Array.prototype.map,一个简单的hexstr.match(/../g).map(function (x) {return String.fromCharCode(parseInt(x, 16))}).join('')就可以完成它。 - outis

0
搜索 toDataUrl() 函数。

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