4

I'm looking for a solution to generate base62 UUIDs in node.js. I'd like to avoid base64 as I intend to create folders based on these UUIDs and characters like =, \, -, _ (as in some implementations) are not that human/filesystem friendly.

Base62 also has the advantage (in my context) of being shorter than a typical v4 UUID.

UPDATE (for clarity): I should have said earlier that I already tried using base62 module but this doesn't solve my issue since base62 takes numbers in javascript integer numbers are only precise up to 52 bits while UUIDs have 128.

Dário
  • 2,002
  • 1
  • 18
  • 28
  • 1
    [`base-x`](https://www.npmjs.com/package/base-x) seems to be a good option to use with [`uuid`](https://www.npmjs.com/package/uuid)'s support for Buffers. The trade-off is that you'll have to specify the character range for base62 as it doesn't have any predefined. – Jonathan Lonowski May 26 '15 at 20:50
  • It does indeed, not sure how I missed it when I searched, thanks Jonathan! In the meantime I've started working on a solution of my own, I'll compare both when I'm done. – Dário May 26 '15 at 20:54
  • I've just compared `b62` against `base-x` and `base-x` is way faster than what I was doing. – Dário May 27 '15 at 10:27
  • Forgot the gist link: [b62.vs.base-x.js](https://gist.github.com/dmarcelino/879d4da2a0e0c32f7d74). – Dário May 27 '15 at 10:35

5 Answers5

11

Here is a comprehensive answer:

Solution A: base-x + node-uuid

Inspired by @Jonathan's earlier comment.

Use node-uuid to generate the UUID and then encode it with base-x:

var buf = new Buffer(16);
var uuid = Uuid.v4(null, buf);
var uuidB62 = baseX.encode(uuid);
// -> 71jbvv7LfRKYp19gtRLtkn

base-x is very fast so this is the most performant solution.

Solution B: uuid-base62

Before knowing about base-x I went ahead and created a module for the base62 encoding (b62) and another for the base62 UUID generation: uuid-base62:

var uuidB62 = uuidBase62.v4();  // -> 2qY9COoAhfMrsH7mCyh86T

This is the no frills solution. Currently it's not as fast as A since b62 is much slower but I intend to replace it with base-x.

UPDATE: uuid-base62 has been updated to use base-x.

Abhijeet
  • 8,561
  • 5
  • 70
  • 76
Dário
  • 2,002
  • 1
  • 18
  • 28
  • `uuid-base62` has been updated to use `base-x` in v0.1.0, so it no longer has the performance penalty it used to have. – Dário Jun 01 '15 at 17:25
  • 1
    Could you please update your answer? I'd like to try out your answer but using Buffer constructor is deprecated and `node-uuid` has been replaced by `uuid` package. – user779159 Sep 20 '18 at 00:19
2

UPDATE: The module I originally pointed out is for converting base 62 numbers to base 10 and vice versa, so that won't do. Looks like original poster is creating their own module to do this: https://github.com/dmarcelino/b62

There is a base62 module that you can use. Here is their sample code:

Base62 = require('base62')
Base62.encode(999)  // 'g7' 
Base62.decode('g7') // 999

The module can be installed with npm install base62. To have it as a dependency in your package.json, use npm install --save base62 instead.

Trott
  • 66,479
  • 23
  • 173
  • 212
  • 1
    Note: The module appears to only support encoding numbers and the size of UUIDs exceeds the possible precision. – Jonathan Lonowski May 26 '15 at 20:42
  • Yes, precisely Jonathan. – Dário May 26 '15 at 20:44
  • Whoops, sorry about that. Well, there's always the node module the original poster is creating: https://github.com/dmarcelino/b62 Updated the answer to include that, but I guess that's not much of an answer. – Trott May 26 '15 at 20:52
  • No worries. Yes, I've started working on it after searching and not finding a solution... I'll post my results once I achieve what I'm looking for. – Dário May 26 '15 at 20:56
0

Install packages:

npm install uuid
npm install base-x

Generate identifier:

const uuid = require('uuid')
const base62 = require('base-x')('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')

const id = base62.encode(Buffer.from(uuid.parse(uuid.v4())))
danijar
  • 32,406
  • 45
  • 166
  • 297
0

Here is a solution for those using Node.js 16+ with just base-x as a dependency:

const crypto = require('crypto');
const BASE62 = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
const base62 = require('base-x')(BASE62);

function generateBase62UUID() {
  const uuid = crypto.randomUUID();
  const buf = Buffer.from(uuid, 'utf-8');
  return base62.encode(buf);
}
anar
  • 529
  • 7
  • 10
-1

npm install base62x

var base62x = require('base62x');

var encoded = base62x.encode('hello');
var decodedBuffer = base62x.decode(encoded);
var decodedString = base62x.decodeString(encoded);

Base62x.class.js is another option for this question. See https://github.com/wadelau/Base62x , https://www.npmjs.com/package/base62x for more information.

Wade Lau
  • 1
  • 1