It's been native BigInts all week long, all week strong and today I'm tying it all in a nice pretty bow with the final installment: How to encode BigInts to Base64, and back again.

If you need to handle signed big ints look at the two articles on converting to and from hex below, that's where all of that is.

With that said, this is a pretty easy - and it's old school. Despite all the advances in JS most of the old thorns remain and, somewhat surprisingly, hex and binary strings are still the easiest way to get some of the most basic stuff done.

Note: For example's sake we're going to use small numbers here, but don't let that fool you, these tiny functions are built for the big ones!

Base64 to BigInt

From Base64 to binary string to hex to BigInt:

function b64ToBn(b64) {
  var bin = atob(b64);
  var hex = [];

  bin.split('').forEach(function (ch) {
    var h = ch.charCodeAt(0).toString(16);
    if (h.length % 2) { h = '0' + h; }
    hex.push(h);
  });

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

Usage:

b64ToBn("AQAB");
// 65537n

atob for node:

// ASCII (base64) to Binary string
function atob(b64) {
  return Buffer.from(b64, 'base64').toString('binary');
}

BigInt to Base64

From BigInt to hex to binary string to Base64:

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

  var bin = [];
  var i = 0;
  var d;
  var b;
  while (i < hex.length) {
    d = parseInt(hex.slice(i, i + 2), 16);
    b = String.fromCharCode(d);
    bin.push(b);
    i += 2;
  }

  return btoa(bin.join(''));
}

Usage:

bnToB64("65537");
// "AQAB"

btoa for node:

// Binary string to ASCII (base64)
function btoa(bin) {
  return Buffer.from(bin, 'binary').toString('base64');
}

URL Safe Base64

If you're BigInts for JWKs you'll need to convert base64 to URL Safe Base64 and back as well.

That's also easy:

function base64ToUrlBase64(str) {
  return str.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
}
function urlBase64ToBase64(str) {
  var r = str % 4;
  if (2 === r) {
    str += '==';
  } else if (3 === r) {
    str += '=';
  }
  return str.replace(/-/g, '+').replace(/_/g, '/');
}

Articles in my JS BigInt Series


By AJ ONeal

If you loved this and want more like it, sign up!


Did I make your day?
Buy me a coffeeBuy me a coffee  

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