简体   繁体   中英

Javascript window.atob -> HEX - different result than expected

I have a BMP image and I need to send it to a device via TCP / IP . We already have the C library in our company, which can handle this, but I need to do it in JavaScript. Unfortunately, I don't have access to the source code of the library, nor to the device system.

This is a Base64 string of a sample image (a black&white checkmark):

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==

I use window.atob and I am encoding it into HEX. I use this JS function:

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);

It gives me this result, which is almost expected result:

424dbe00000003e0002800020000200001010000080000c4e00c4e00000000000000ffffff0ffffffffffe1ffffffc0ffffff807fffff07ffffe03ffffc03ffff801ffff00fffe00fffc807ff9c07ffbc103ff7e301ff7f781ffbef80ffbcfc07fc3fe07ffffe03fffff401fffffbf9fffffbfcfffffdfc7ffffefe3ffffeff3fffff7f1fffffbf9fffffdfcfffffefdfffffefdffffff7bffffff87

The library sends the exact same image correctly (the device accepts the message). This is how it looks like (copied from log):

be00424dbe000000000000003e000000280000002000000020000000010001000000000080000000c40e0000c40e0000000000000000000000000000ffffff00ffffffffffe1ffffffc0ffffff807fffff007ffffe003ffffc003ffff8001ffff0000fffe0000fffc80007ff9c0007ffbc10101003ff7e3001ff7f7801ffbef800ffbcfc007fc3fe007ffffe003fffff401fffffbf9fffffbfcfffffdfc7ffffefe3ffffeff3fffff7f1fffffbf9fffffdfcfffffefdfffffefdffffff7bffffff87

So this is what I need to get from Base64 in my JavaScript. Is it even possible? Or am I missing something?

Documentation for the library says the image has to be 2B binary data (Little Endian). I don't understand it. Should I encode the image any other way?

One option would be encode each byte separately to ensure correct endianness.

 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('')) 

This doesn't match your desired output exactly, are you sure it corresponds to the given base64 string?

On the other side, your initial output looks better, 424d are correct bytes to start a BMP file ( BM signature), while be00 are not.

This is a Base64 string of a sample image (a black&white checkmark)...
It gives me this result, which is almost expected result:

 424dbe00000003e0002800020000200001010000080000c4e00c4e00000000000000ffffff0ffffffffffe1ffffffc0ffffff807fffff07ffffe03ffffc03ffff801ffff00fffe00fffc807ff9c07ffbc103ff7e301ff7f781ffbef80ffbcfc07fc3fe07ffffe03fffff401fffffbf9fffffbfcfffffdfc7ffffefe3ffffeff3fffff7f1fffffbf9fffffdfcfffffefdfffffefdffffff7bffffff87 

What do you mean by "almost expected result" ?, those bytes make the image below (save as .bmp ).
Your expected "a black&white checkmark" image :

PS:

The correct .bmp file has 190 bytes. Your library version (copied from logs) gives result of 194 bytes.

The library's version of bytes has a beginning 2-byte short for file size.
That is BE 00 ( = 190 when read as endian of 00 BE ) followed by rest of Bitmap file bytes (190 total bytes). This makes total of 190 bytes + the 2 bytes of short . Then it adds these two mysterious 10 and 10 bytes starting at position 114. Grand total of 194 bytes.

To me... the library is corrupting the already fine image bytes, but you say the device accepts it?
Does it accept the "almost expected result" hex bytes too?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM