We now have native `BigInt`s in JavaScript (not just 64-bit integers, but any arbitrary precision of integer with no pre-defined bit-width). Yay!

However, BigInts have a sordid past... and JavaScript has a sordid past, so the new `BigInt` primitives are shimmed in and both hold to old, unhelpful JS conventions as well as break some new conventions because, well, it's just how the cookie crumbled.

TL;DR:

For the impatient, this is what we're building up to:

`bnToBuf(bn)`:

``````function bnToBuf(bn) {
var hex = BigInt(bn).toString(16);
if (hex.length % 2) { hex = '0' + hex; }

var len = hex.length / 2;
var u8 = new Uint8Array(len);

var i = 0;
var j = 0;
while (i < len) {
u8[i] = parseInt(hex.slice(j, j+2), 16);
i += 1;
j += 2;
}

return u8;
}
``````

`bufToBn(buf)`:

``````function bufToBn(buf) {
var hex = [];
u8 = Uint8Array.from(buf);

u8.forEach(function (i) {
var h = i.toString(16);
if (h.length % 2) { h = '0' + h; }
hex.push(h);
});

return BigInt('0x' + hex.join(''));
}
``````

Usage:

``````bnToBuf('1234567890123456789012345678901234567890');
// Uint8Array [ 3, 160, 201, 32, 117, 192, 219, 243,
184, 172, 188, 95, 150, 206, 63, 10, 210 ]

bufToBn([ 3, 160, 201, 32, 117, 192, 219, 243,
184, 172, 188, 95, 150, 206, 63, 10, 210 ]);
// 1234567890123456789012345678901234567890n
``````

And if you need to handle negative numbers, you'll need to take a look at How to Convert JS Signed BigInts to Hex

## BigInt64Arrays are not exactly TypedArrays

When you're glancing over the almost non-existent documentation for `BigInt` you'll likely come across `BigInt64Array` and `BigUint64Array`, which are mostly unrelated.

As the name implies, these ints are not true `BigInt`s, but rather capped at 64-bits wide.

However, they aren't just `Number`s either.

`Number`s can only survive normal bitwise operations up to 31-bits. With a little triple-shift trickery they can be coaxed into behaving well will a full 32 bits, but the full width 52-bit integers is not supported.

These `BigInt64Array` elements will work with many bitwise operations (though signed / negative numbers are still problematic for some operations).

Also, they're not compatible with other `TypedArray`s.

This snippet, for example, won't work:

``````var bns = BigInt64Array.from([ BigInt(1), BigInt(2), BigInt(3), BigInt(4) ]);
var u8 = Uint8Array.from(bns);
``````

It throws an exception.

And despite being able to access it's `ArrayBuffer` you can't use that either:

``````var u8 = Uint8Array.from(bns.buffer);
``````

However, it turns out that if you do it just right, you can get access to the bytes by calling `new`:

``````var u8 = new Uint8Array(bns.buffer);
``````

Likewise you can ever-so-carefully convince it to go into a `DataView` as well:

``````var dv = new DataView(bns.buffer);
``````

Here's the rub:

Even then you're capped to 64-bits. You can't even convert from a `BigInt` as you might suspect:

``````BigInt64Array.from(BigInt('12345678901234567890123456781234567783456')); // BigInt64Array []

BigInt64Array.from([ BigInt('12345678901234567890123456781234567783456') ]);
// BigInt64Array [ -4657930579192962016 ]
``````

## Converting from BigInts to Arrays/Buffers

So, ultimately, if you want to get a `BigInt` that's larger than 64-bits wide into indidivual bytes, you have to do it the old fashioned way - with hex (or binary strings):

``````function bnToBuf(bn) {
// The handy-dandy `toString(base)` works!!
var hex = BigInt(bn).toString(16);

// But it still follows the old behavior of giving
// invalid hex strings (due to missing padding),
// but we can easily add that back
if (hex.length % 2) { hex = '0' + hex; }

// The byteLength will be half of the hex string length
var len = hex.length / 2;
var u8 = new Uint8Array(len);

// And then we can iterate each element by one
// and each hex segment by two
var i = 0;
var j = 0;
while (i < len) {
u8[i] = parseInt(hex.slice(j, j+2), 16);
i += 1;
j += 2;
}

return u8;
}
``````

And thus we can handle integers of arbirary length in buffers, yay!

``````bnToBuf('1234567890123456789012345678901234567890')
// Uint8Array [ 3, 160, 201, 32, 117, 192, 219, 243,
184, 172, 188, 95, 150, 206, 63, 10, 210 ]
``````

## Converting an ArrayBuffer to BigInt

By comparison, this is reverse is super simple.

``````function bufToBn(buf) {
var hex = [];
u8 = Uint8Array.from(buf);

u8.forEach(function (i) {
var h = i.toString(16);
if (h.length % 2) { h = '0' + h; }
hex.push(h);
});

return BigInt('0x' + hex.join(''));
}
``````

There aren't any real gotchas - unless you're working with signed BigInts, in which case you'll want to read up on that specifically.

I cover negative number encoding and decoding in the artciles on converting between hex and decimal listed below:

## Looking for more?

If you found this useful, and you're interested in solving related problems, take a look at these as well:

## References

By AJ ONeal (you can learn about the bigger picture I'm working towards on my patreon page )

#### Published

2018-12-13 73% of Goal Reached

Want more like this?