npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

objectid64

v5.2.1

Published

The fastest way to convert ids, UUID, MongoDB ObjectId into shorter, URL-friendly base64 and vice versa.

Downloads

38

Readme

ObjectId64

Actions Status npm

The library offers the Encoder class to convert UUIDs, ObjectIds, numbers, and bigints to and from Base64 with a configurable character set. By default, the encoder uses the url-friendly alphabet of base64url(A-Z a-z 0-9 - _).

The Encrypter class can be used to further secure structured and sequential ids from intelligence leaks by encrypting them into 128-bit (UUID-like) values using built-in Web Crypto API.

Features:

  • Encoder with a configurable alphabet for obfuscating ids.
  • Shorter id strings when compared to canonical hex strings:
    • UUID results in 22 characters against canonical 36
    • ObjectId is 16 instead of 24 hex characters
  • As fast as JavaScript gets. Encoding to/from binary even faster than canonical encoding to/from hex strings.
  • Strong encryption using built-in Web Crypto API.

Read more in An Exercise in Shortening Ids.

Usage

Installation

In Node.js

npm i objectid64
import { Encoder, Encrypter } from "objectid64";

In Deno:

import {
  Encoder,
  Encrypter,
} from "https://raw.githubusercontent.com/zandaqo/objectid64/3.2.0/mod.ts";

Custom Encoder

Instantiate a new encoder with the desired alphabet. The alphabet is a string of 64 characters where the character position determines the resulting encoding. By varying the position, we can create different encodings, for example, to obfuscate numerical ids. If no alphabet is provided, the default base64url will be used:

const defaultEncoder = new Encoder();

const customEncoder = new Encoder(
  "KLMNOPQRSTUVWXYZabcdefghijklmnopqr23456stuvwxyzABCDEFGHIJ01789-_",
);

If you are not going to deal with hex strings of UUIDs or ObjectIds, set the second parameter of the encoder constructor (noLookup) to true to avoid generating lookup tables for hex conversions:

const defaultEncoder = new Encoder(null, true);

Obfuscating Sequential Ids

By using different alphabets, we can encode numerical ids into different Base64 strings:

defaultEncoder.fromInt(86576);
//=> "VIw"
defaultEncoder.toInt("VIw");
//=> 86576

customEncoder.fromInt(86576);
//=> "fSB"
customEncoder.toInt("fSB");
//=> 86576

For sequential ids represented by 64-bit integers, we can use JavaScript's bigints:

customEncoder.fromBigInt(2989452080569002368n);
//=> "M58vyahh26K"
customEncoder.toBigInt("M58vyahh26K");
//=> 2989452080569002368n

customEncoder.fromBigInt(2989452080569002368n);
//=> "M58vyahh26K"
customEncoder.toBigInt("M58vyahh26K");
//=> 2989452080569002368n

Binary UUIDS and ObjectIds

The encoder supports direct encoding of binary UUIDs and ObjectIds to and from Base64, and does so almost twice as fast as other implementations encoding into canonical hex strings.

const objectId = new ObjectId("581653766c5dbc10f0aceb55");
objectId.id;
//=> Uint8Array [88 ... 85]
defaultEncoder.fromBinObjectId(objectId.id);
//=> "WBZTdmxdvBDwrOtV"
defaultEncoder.toBinObjectId("WBZTdmxdvBDwrOtV");
//=> Uint8Array [88 ... 85]

const uuid = new Uint8Array([0x6d, ..., 0x9f]);
defaultEncoder.fromBinUUID(uuid);
//=> "ygtwdVymRMenB4rdSkqHDS"
defaultEncoder.toBinUUID("ygtwdVymRMenB4rdSkqHDS");
//=> new Uint8Array([0x6d, ..., 0x9f])

Hex UUIDs and ObjectIds

Encoder also supports coversion between the canonical id hex strings and Base64:

const encoder = new Encoder();

const objectId = new ObjectId();
const hex = objectId.toHexString();
//=> '581653766c5dbc10f0aceb55'
let encoded = encoder.fromObjectId(hex);
//=> 'WBZTdmxdvBDwrOtV'
let decoded = encoder.toObjectId(encoded);
//=> '581653766c5dbc10f0aceb55'
// or back to binary
decoded = encoder.toBinObjectid(encoded);
// => Uint8Array [...]

const uuid = crypto.randomUUID();
//=> "6d2bb408-3176-42d3-b473-3d251f19569f"
encoded = encoder.fromUUID(uuid);
//=> "bSu0CDF2QtO0cz0lHxlWCf"
decoded = encoder.toUUID(encoded);
//=> "6d2bb408-3176-42d3-b473-3d251f19569f"

Id Encryption

While encoding with custom character sets can achieve certain obfurscation, it is not a strong encryption. To secure structured ids from business intelligence leaks where it really matters, one should use strong encryption algorithms. Hence, Encrypter class provides an interface for encrypting ids into UUID-like 128-bit values using AES encryption offered by Web Crypto API.

const encoder = new Encoder();
// generates 128-bit AES-CRT key to use in our encrypter
const key = await Encrypter.generateKey();
const encrypter = new Encrypter(key);
const objectId = new ObjectId();
encoder.fromBinObjectId(objectId.id);
//=> WBZTdmxdvBDwrOtV
const encrypted = await encrypter.fromObjectId(objectId.id);
encoder.fromBinUUID(encrypted);
//=> zSrTRzGRrRZOVR5_2gbDBd
const decrypted = await encrypter.toObjectId(encrypted);
encoder.fromBinObjectId(decrypted);
//=> WBZTdmxdvBDwrOtV

Benchmark

> deno bench --unstable
benchmark                                time (avg)             (min … max)       p75       p99      p995
--------------------------------------------------------------------------- -----------------------------
[ObjectId Hex to Base64] ObjectId64    1.26 µs/iter     (1.19 µs … 1.67 µs)   1.28 µs   1.67 µs   1.67 µs
BigInt                                 5.95 µs/iter     (5.86 µs … 6.28 µs)   5.96 µs   6.28 µs   6.28 µs
base64-mongo-id                        2.72 µs/iter     (2.56 µs … 4.43 µs)   2.72 µs   4.43 µs   4.43 µs

summary
  [ObjectId Hex to Base64] ObjectId64
   2.15x faster than base64-mongo-id
   4.71x faster than BigInt

[UUID Hex to Base64] ObjectId64        2.51 µs/iter     (2.25 µs … 3.78 µs)   2.47 µs   3.78 µs   3.78 µs
uuid-base64                            8.67 µs/iter      (6.5 µs … 3.01 ms)      8 µs   23.8 µs   25.7 µs

summary
  [UUID Hex to Base64] ObjectId64
   3.45x faster than uuid-base64

[UUID Binary] ObjectId64               3.13 µs/iter      (2.1 µs … 4.23 ms)    2.6 µs    8.5 µs   13.6 µs
id128 ULID                             4.44 µs/iter     (3.1 µs … 17.98 ms)    3.9 µs     12 µs   20.3 µs
id128 UUID                             43.8 µs/iter      (4.6 µs … 4.16 ms)   54.9 µs    112 µs  141.6 µs

summary
  [UUID Binary] ObjectId64
   1.42x faster than id128 ULID
   14.01x faster than id128 UUID

[ObjectId Binary] ObjectId64           1.81 µs/iter     (1.39 µs … 4.99 µs)   1.87 µs   4.99 µs   4.99 µs
BSON                                    4.4 µs/iter       (3.6 µs … 5.1 ms)      4 µs   13.2 µs   19.2 µs

summary
  [ObjectId Binary] ObjectId64
   2.44x faster than BSON

[UUID Encode/Encrypt] Encode UUID      2.36 µs/iter      (2.12 µs … 4.4 µs)   2.16 µs    4.4 µs    4.4 µs
Encrypt UUID                         209.52 µs/iter    (150.3 µs … 3.59 ms)  209.4 µs  501.6 µs  700.1 µs

summary
  [UUID Encode/Encrypt] Encode UUID
   88.69x faster than Encrypt UUID

[Int Encode/Encrypt] Encode Int      318.29 ns/iter (281.78 ns … 736.37 ns) 296.57 ns 662.18 ns 736.37 ns
Encrypt Int                          198.17 µs/iter    (156.4 µs … 4.18 ms)  187.9 µs  436.3 µs  605.5 µs

summary
  [Int Encode/Encrypt] Encode Int
   622.62x faster than Encrypt Int

License

MIT © Maga D. Zandaqo