Reputation: 1273
I am working on some decoding in nodejs, and have a buffer:
59 19 F2 92 8C 88 88 88 89 88 EB 89 88 88 A1 8A
88 88 88 88 89 88 A8 CD 88 88 88 DB 88 88 88 DC
88 88 88 A5 88 88 88 BD 88 88 88 B2 88 88 88 B8
88 88 88 B8 88 88 88 8A 88 89 89 8D 88 89 8D 8E
88 89 89 8F 88 89 89 80 88 8C 87 88 88 88 81 88
89 8B 82 88 8C 9C 88 88 88 85 88 8C 88 88 88 88
87 88 89 8A 99 88 89 88 9B 88 8C 8D 88 88 88 9C
88 8C 8D 88 88 88 9D 88 8C 8D 88 88 88 9E 88 8C
A0 88 88 88 9F 88 94 DA 88 88 88 ED 88 88 88 FE
88 88 88 ED 88 88 88 FA 88 88 88 FB 88 88 88 ED
88 88 88 90 88 90 C4 88 88 88 E1 88 88 88 EF 88
88 88 E0 88 88 88 FC 88 88 88 FB 88 88 88 91 88
AC C4 88 88 88 ED 88 88 88 EE 88 88 88 FC 88 88
88 A8 88 88 88 DC 88 88 88 FD 88 88 88 FA 88 88
88 E6 88 88 88 92 88 A0 DA 88 88 88 E1 88 88 88
EF 88 88 88 E0 88 88 88 FC 88 88 88 A8 88 88 88
The requirement doc says it is encoded XOR the byte against 0x77 then take the complementary byte.
So
59 XOR 77 => 2E (00101110) => D1 (11010001)
19 XOR 77 => 6E (01101110) => 91 (10010001)
What is the best way in node to do this and end with a buffer with the needed bytes?
Upvotes: 4
Views: 1847
Reputation: 8580
dvlsg's answer is spot on functionally and received my upvote.
However, as they noted, their solution is "probably slower" (it's considerably slower -- though negligible for smaller buffers). The bitwise operators are performing calculations using 32-bit registers, yet if doing this bit manipulation byte by byte, it'll cost one 4x as many operations. In Addition to that. Array built in functions like .map and .forEach are doing a lot of tedious and unnecessary things behind the scenes for this low level crunching (those methods are geared toward immutability and functional programming -- a lot of data copying is going on behind the scenes during execution).
If you're doing binary manipulation, you most likely want to do the following instead:
// presuming `buffer` has your raw binary buffer
let wrapperUint32Array = new Uint32Array(buffer)
let end = wrapperUint32Array.length;
let i = 0;
while(i < end){
wrapperUint32Array[i] = ~(0x77777777 ^ wrapperUint32Array[i])
i++;
}
// your original buffer was manipulated/contains inverted bytes
Although, equally important to note, above only works if the buffer is divisible by 4 without remainders. If it's not, yet an even number of bytes are in the buffer, Uint16 could be used instead. If an odd number, Uint8 would need to be used like the following instead as well. We'd be performing more operations (similar in number to the Array map), but no data is being copied and iteration is still much quicker with this approach.
// presuming `buffer` has your raw binary buffer
let end = buffer.byteLength;
let i = 0;
let wrapperUint8Array = new Uint8Array(buffer)
while(i < end){
wrapperUint8Array[i] = ~(0x77 ^ wrapperUint8Array[i])
i++;
}
// your original buffer was manipulated/contains inverted bytes
Some key points:
Upvotes: 1
Reputation: 5538
You could try this:
let buf = new Buffer([ 0x59, 0x19, 0xF2, 0x92 ]); // etc.
let converted = new Buffer(
Array.from(buf)
.map(x => x ^ 0x77)
.map(x => ~x)
);
// output: <Buffer d1 91 7a 1a>
This probably won't be the fastest way (Array.from
instead of just iterating over the buffer one by one is probably slower, and I opted for 2 separate maps instead of just 1 for readability) but it should at least get you started.
Upvotes: 3