我有JavaScript代码,可以从Web服务中检索数字向量 . 原始数据是一个双精度数组,转换为字节数组然后进行base64编码 . 我在JavaScript中从base64解码,但后来我不知道如何将结果字节转换为数字数组 .
这是我能想到的唯一方法 .
function bytesToDouble(str,start) { start *= 8; var data = [str.charCodeAt(start+7), str.charCodeAt(start+6), str.charCodeAt(start+5), str.charCodeAt(start+4), str.charCodeAt(start+3), str.charCodeAt(start+2), str.charCodeAt(start+1), str.charCodeAt(start+0)]; var sign = (data[0] & 1<<7)>>7; var exponent = (((data[0] & 127) << 4) | (data[1]&(15<<4))>>4); if(exponent == 0) return 0; if(exponent == 0x7ff) return (sign) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY; var mul = Math.pow(2,exponent - 1023 - 52); var mantissa = data[7]+ data[6]*Math.pow(2,8*1)+ data[5]*Math.pow(2,8*2)+ data[4]*Math.pow(2,8*3)+ data[3]*Math.pow(2,8*4)+ data[2]*Math.pow(2,8*5)+ (data[1]&15)*Math.pow(2,8*6)+ Math.pow(2,52); return Math.pow(-1,sign)*mantissa*mul; } var data = atob("AAAAAABsskAAAAAAAPmxQAAAAAAAKrF"); alert(bytesToDouble(data,0)); // 4716.0 alert(bytesToDouble(data,1)); // 4601.0
这应该会给你一个正确的方向,虽然我花了一段时间来记住如何处理doubles .
但需要注意的一个重要注意事项:
这依赖于 atob 进行base64解码,这在任何地方都不受支持,除此之外,这可能不是一个好主意 . 你真正想要做的是将base64编码的字符串展开到一个数字数组(字节将是最容易使用的,尽管不是地球上最有效的东西) . 原因是当 atob 发挥其魔力时,它会返回一个远非理想的字符串 . 根据编码它映射到的代码点(特别是对于128到255之间的代码点),生成的 .charCodeAt() 可能不会返回您期望的结果 .
atob
.charCodeAt()
并且可能存在一些准确性问题,因为毕竟我使用双倍来计算双倍,但我认为它可能没问题 .
使用Base64非常简单,因此您应该能够找出该部分 .
如果你确实切换到一个数组(而不是现在的 str 字符串),那么你显然会删除 .charCodeAt() 引用并直接得到你想要的索引 .
str
有一个functioning fiddle here
我假设我们已经在Web服务(c#)中使用此函数将双数组数据编码为字符串:
//Input: [552.4, 539.8] //Output: IOz0gCAsscA= private string ConvertToSerializableString(double[] input) { byte[] data = new byte[input.Length * 4]; for (int i = 0; i < input.Length; i++) { int source = (int)(input[i] * 1E6); int dataIndex = i * 4; data[dataIndex] = (byte)((source >> 24) & 0xFF); data[dataIndex + 1] = (byte)((source >> 16) & 0xFF); data[dataIndex + 2] = (byte)((source >> 8) & 0xFF); data[dataIndex + 3] = (byte)(source & 0xFF); } return Convert.ToBase64String(data); }
然后我们可以使用以下客户端脚本(javascript)对其进行解码:
var base64EncodedDoubleArrayData = "IOz0gCAsscA="; var byteData = window.atob(base64EncodedDoubleArrayData); var doubleArray = []; for (var iColumn = 0; iColumn < byteData.length; iColumn = iColumn + 4) { var item = (byteData.charCodeAt(iColumn) << 24) + (byteData.charCodeAt(iColumn + 1) << 16) + (byteData.charCodeAt(iColumn + 2) << 8) + byteData.charCodeAt(iColumn + 3); var doubleResult = parseFloat(item/1e6); doubleArray.push(doubleResult); } //it should return something like doubleArray = [552.4, 539.8]
2 回答
这是我能想到的唯一方法 .
这应该会给你一个正确的方向,虽然我花了一段时间来记住如何处理doubles .
但需要注意的一个重要注意事项:
这依赖于
atob
进行base64解码,这在任何地方都不受支持,除此之外,这可能不是一个好主意 . 你真正想要做的是将base64编码的字符串展开到一个数字数组(字节将是最容易使用的,尽管不是地球上最有效的东西) . 原因是当atob
发挥其魔力时,它会返回一个远非理想的字符串 . 根据编码它映射到的代码点(特别是对于128到255之间的代码点),生成的.charCodeAt()
可能不会返回您期望的结果 .并且可能存在一些准确性问题,因为毕竟我使用双倍来计算双倍,但我认为它可能没问题 .
使用Base64非常简单,因此您应该能够找出该部分 .
如果你确实切换到一个数组(而不是现在的
str
字符串),那么你显然会删除.charCodeAt()
引用并直接得到你想要的索引 .有一个functioning fiddle here
我假设我们已经在Web服务(c#)中使用此函数将双数组数据编码为字符串:
然后我们可以使用以下客户端脚本(javascript)对其进行解码: