3

I have a byte array:

[101, 97, 115, 121] # ['e', 'a', 's', 'y']

How can I interpret it as a packed binary? Something like struct.Struct(format).unpack in Python:

>>> import struct
>>> s = struct.Struct('>1I') # a big-endian, two-byte, unsigned int
>>> s.unpack('easy')
(1700885369,)

Is there a way to implement this in JavaScript without an import?

poke
  • 369,085
  • 72
  • 557
  • 602
Zach Gates
  • 4,045
  • 1
  • 27
  • 51
  • possible duplicate of [pack / unpack functions for node.js](http://stackoverflow.com/questions/5605108/pack-unpack-functions-for-node-js) – Carsten Apr 14 '15 at 21:59
  • You'll want to have a look at [`DataView`s](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView) – Bergi Apr 15 '15 at 01:15

1 Answers1

6

There is no built-in way to do this in JavaScript. However, there are various ports of Python’s struct module which you can use to exactly copy the functionality, e.g. jspack.

If you only want to have a single (or a few) operations though, you can easily implement it yourself:

var bytes = [101, 97, 115, 121];
var unpacked = bytes.reduce(function (s, e, i) { return s | e << ((3 - i) * 8); }, 0);
console.log(unpacked); // 1700885369

That is essentially a fancy way of doing this:

121 | 115 << 8 | 97 << 16 | 101 << 24

or written using the indices:

bytes[3] | bytes[2] << ((3-2) * 8) | bytes[1] << ((3-1) * 8) | bytes[0] << ((3-0) * 8)

And the other way around:

var number = 1700885369;
var bytes = [];
while (number > 0) {
    bytes.unshift(number & 255);
    number >>= 8;
}
console.log(bytes); // [101, 97, 115, 121]
poke
  • 369,085
  • 72
  • 557
  • 602
  • How could I get back to the byte array from `unpacked`? – Zach Gates Apr 14 '15 at 22:44
  • @ZachGates, do you mean like this? nr = 0; while (n = bytes.shift()) { nr <<= 8; nr |= n; } console.log(nr); – Nicolai Nita Sep 25 '17 at 12:52
  • @NicolaiNita I edited my answer back then to include the other way around. – poke Sep 25 '17 at 13:09
  • Just a quick note. This answer only works for values less than 2,147,483,648. This is because Javascript treats bitwise values as 32 bit signed integers. This means that the left most bit is used as the "sign" meaning that if the left most bit is a 1, then the number is negative. Just try unpacking `[255, 255, 255, 255]` and you'll get `-1`. So while it's definitely possible to unpack larger values, it's not as straight forward to accomplish. – Ray Perea Apr 06 '19 at 12:32