Javascript window.atob - > HEX - 与预期不同的结果

时间:2017-01-26 15:04:36

标签: javascript base64 hex byte

我有BMP图片,我需要通过TCP / IP将其发送到设备。我们公司已经有C库,可以处理这个,但我需要在JavaScript中完成。不幸的是,我无法访问库的源代码,也无法访问设备系统。

这是示例图片的Base64字符串(黑色和白色复选标记):

  

Qk2 + AAAAAAAAAD4AAAAoAAAAIAAAACAAAAABAAEAAAAAAIAAAADEDgAAxA4AAAAAAAAAAAAAAAAAAP /// WD ////// + H //// ////甲///的gH WB /// 4AP // // 8AD + AAF // // AAD GAA / / yAAH / 5wAB / + 8EAP / fjAB / 394Af +++ AD / vPwAf8P + AH /// GA /// 9AH /// V5 /// 7 / P /// FX /// 7 + P + // / Z /// 38F // + / N /// 38 /// + / F /// V3 /// 97 //// HW ==

我使用window.atob并将其编码为HEX。我使用这个JS函数:

function toHex(str) {
    var result = '';
    for (var i = 0; i < str.length; i++) {
        result += str.charCodeAt(i).toString(16);
    }
    return result;
}
var str = window.atob(base64img);
var result = toHex(str);

它给了我这个结果,这几乎是预期的结果:

  

424dbe00000003e0002800020000200001010000080000c4e00c4e00000000000000ffffff0ffffffffffe1ffffffc0ffffff807fffff07ffffe03ffffc03ffff801ffff00fffe00fffc807ff9c07ffbc103ff7e301ff7f781ffbef80ffbcfc07fc3fe07ffffe03fffff401fffffbf9fffffbfcfffffdfc7ffffefe3ffffeff3fffff7f1fffffbf9fffffdfcfffffefdfffffefdffffff7bffffff87

库正确发送完全相同的图像(设备接受该消息)。这是它的样子(从日志中复制):

  

be00424dbe000000000000003e000000280000002000000020000000010001000000000080000000c40e0000c40e0000000000000000000000000000ffffff00ffffffffffe1ffffffc0ffffff807fffff007ffffe003ffffc003ffff8001ffff0000fffe0000fffc80007ff9c0007ffbc10101003ff7e3001ff7f7801ffbef800ffbcfc007fc3fe007ffffe003fffff401fffffbf9fffffbfcfffffdfc7ffffefe3ffffeff3fffff7f1fffffbf9fffffdfcfffffefdfffffefdffffff7bffffff87

所以这就是我需要从JavaScript中Base64获取的内容。它甚至可能吗?或者我错过了什么?

图书馆的文档说图像必须是2B二进制数据(Little Endian)。我不明白。我应该以其他方式编码图像吗?

2 个答案:

答案 0 :(得分:0)

一个选项是分别对每个字节进行编码,以确保正确的字节顺序。

img = "Qk2+AAAAAAAAAD4AAAAoAAAAIAAAACAAAAABAAEAAAAAAIAAAADEDgAAxA4AAAAAAAAAAAAAAAAAAP///wD//////+H////A////gH///wB///4AP//8AD//+AAf//AAD//gAA//yAAH/5wAB/+8EAP/fjAB/394Af+++AD/vPwAf8P+AH///gA///9AH///v5///7/P///fx///7+P//+/z///38f//+/n///38///+/f///v3///97////hw=="

str = atob(img)

buf = []

function hex(str, pos) {
  return ('000' + (str.charCodeAt(pos) || 0).toString(16)).substr(-2);
}


for (var i = 0; i < str.length; i+= 4) {
  buf.push(hex(str, i+2));
  buf.push(hex(str, i+3));
  buf.push(hex(str, i+0));
  buf.push(hex(str, i+1));
}

console.log(buf.join(''))

这与您想要的输出完全匹配,您确定它对应于给定的base64字符串吗?

另一方面,您的初始输出看起来更好,424d是启动BMP文件(BM签名)的正确字节,而be00则不是。

答案 1 :(得分:0)

  

这是样本图像的Base64字符串(黑色和白色复选标记)...
  它给了我这个结果,这几乎是预期的结果:

424dbe00000003e0002800020000200001010000080000c4e00c4e00000000000000ffffff0ffffffffffe1ffffffc0ffffff807fffff07ffffe03ffffc03ffff801ffff00fffe00fffc807ff9c07ffbc103ff7e301ff7f781ffbef80ffbcfc07fc3fe07ffffe03fffff401fffffbf9fffffbfcfffffdfc7ffffefe3ffffeff3fffff7f1fffffbf9fffffdfcfffffefdfffffefdffffff7bffffff87

“几乎预期的结果”是什么意思?,这些字节使下面的图像(另存为 .bmp )。
您预期的 "a black&white checkmark" 图片:

PS:

正确的 .bmp 文件有190个字节。您的库版本(从日志中复制)给出了194个字节的结果。

库的字节版本对于文件大小有一个2字节short的开头。
BE 00作为= 190的结尾时,00 BE short )后跟剩余的Bitmap文件字节(总共190个字节)。这使得总共190个字节+ 10的2个字节。然后它从位置114开始添加这两个神秘的10function params(data) { return Object.keys(data).map(key => `${key}=${encodeURIComponent(data[key])}`).join('&'); } console.log(params({foo: 'bar'})); console.log(params({foo: 'bar', baz: 'qux$'}));字节。总共194个字节。

对我来说......图书馆正在破坏已经很好的图像字节,但是你说设备接受它了吗? 它是否也接受“几乎预期的结果”十六进制字节?