{"id":18285518,"url":"https://github.com/zandaqo/objectid64","last_synced_at":"2025-04-05T07:32:23.623Z","repository":{"id":47215927,"uuid":"72995937","full_name":"zandaqo/objectid64","owner":"zandaqo","description":"The fastest way to convert UUID, MongoDB ObjectID, and serial ids into shorter, URL-friendly base64 and vice versa.","archived":false,"fork":false,"pushed_at":"2022-10-29T09:37:47.000Z","size":344,"stargazers_count":16,"open_issues_count":2,"forks_count":7,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-15T00:10:03.150Z","etag":null,"topics":["base64","compression","encoder","objectid","serializer","uuid"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zandaqo.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-11-06T14:27:48.000Z","updated_at":"2024-04-06T01:58:30.000Z","dependencies_parsed_at":"2022-08-12T13:20:15.329Z","dependency_job_id":null,"html_url":"https://github.com/zandaqo/objectid64","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zandaqo%2Fobjectid64","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zandaqo%2Fobjectid64/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zandaqo%2Fobjectid64/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zandaqo%2Fobjectid64/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zandaqo","download_url":"https://codeload.github.com/zandaqo/objectid64/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247305879,"owners_count":20917201,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["base64","compression","encoder","objectid","serializer","uuid"],"created_at":"2024-11-05T13:16:55.837Z","updated_at":"2025-04-05T07:32:18.613Z","avatar_url":"https://github.com/zandaqo.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ObjectId64\n\n[![Actions Status](https://github.com/zandaqo/objectid64/workflows/ci/badge.svg)](https://github.com/zandaqo/objectid64/actions)\n[![npm](https://img.shields.io/npm/v/objectid64.svg?style=flat-square)](https://www.npmjs.com/package/objectid64)\n\nThe library offers the `Encoder` class to convert UUIDs, ObjectIds, numbers, and\nbigints to and from Base64 with a configurable character set. By default, the\nencoder uses the url-friendly alphabet of `base64url`(`A-Z a-z 0-9 - _`).\n\nThe `Encrypter` class can be used to further secure structured and sequential\nids from intelligence leaks by encrypting them into 128-bit (UUID-like) values\nusing built-in Web Crypto API.\n\nFeatures:\n\n- Encoder with a configurable alphabet for obfuscating ids.\n- Shorter id strings when compared to canonical hex strings:\n  - UUID results in 22 characters against canonical 36\n  - ObjectId is 16 instead of 24 hex characters\n- As fast as JavaScript gets. Encoding to/from binary even faster than canonical\n  encoding to/from hex strings.\n- Strong encryption using built-in Web Crypto API.\n\nRead more in\n[An Exercise in Shortening Ids](https://itnext.io/an-exercise-in-shortening-ids-902b723fdd91).\n\n## Usage\n\n### Installation\n\nIn Node.js\n\n```bash\nnpm i objectid64\n```\n\n```javascript\nimport { Encoder, Encrypter } from \"objectid64\";\n```\n\nIn Deno:\n\n```javascript\nimport {\n  Encoder,\n  Encrypter,\n} from \"https://raw.githubusercontent.com/zandaqo/objectid64/3.2.0/mod.ts\";\n```\n\n### Custom Encoder\n\nInstantiate a new encoder with the desired alphabet. The alphabet is a string of\n64 characters where the character position determines the resulting encoding. By\nvarying the position, we can create different encodings, for example, to\nobfuscate numerical ids. If no alphabet is provided, the default `base64url`\nwill be used:\n\n```javascript\nconst defaultEncoder = new Encoder();\n\nconst customEncoder = new Encoder(\n  \"KLMNOPQRSTUVWXYZabcdefghijklmnopqr23456stuvwxyzABCDEFGHIJ01789-_\",\n);\n```\n\nIf you are not going to deal with hex strings of UUIDs or ObjectIds, set the\nsecond parameter of the encoder constructor (`noLookup`) to `true` to avoid\ngenerating lookup tables for hex conversions:\n\n```javascript\nconst defaultEncoder = new Encoder(null, true);\n```\n\n### Obfuscating Sequential Ids\n\nBy using different alphabets, we can encode numerical ids into different Base64\nstrings:\n\n```javascript\ndefaultEncoder.fromInt(86576);\n//=\u003e \"VIw\"\ndefaultEncoder.toInt(\"VIw\");\n//=\u003e 86576\n\ncustomEncoder.fromInt(86576);\n//=\u003e \"fSB\"\ncustomEncoder.toInt(\"fSB\");\n//=\u003e 86576\n```\n\nFor sequential ids represented by 64-bit integers, we can use JavaScript's\n`bigints`:\n\n```javascript\ncustomEncoder.fromBigInt(2989452080569002368n);\n//=\u003e \"M58vyahh26K\"\ncustomEncoder.toBigInt(\"M58vyahh26K\");\n//=\u003e 2989452080569002368n\n\ncustomEncoder.fromBigInt(2989452080569002368n);\n//=\u003e \"M58vyahh26K\"\ncustomEncoder.toBigInt(\"M58vyahh26K\");\n//=\u003e 2989452080569002368n\n```\n\n### Binary UUIDS and ObjectIds\n\nThe encoder supports direct encoding of binary UUIDs and ObjectIds to and from\nBase64, and does so almost twice as fast as other implementations encoding into\ncanonical hex strings.\n\n```javascript\nconst objectId = new ObjectId(\"581653766c5dbc10f0aceb55\");\nobjectId.id;\n//=\u003e Uint8Array [88 ... 85]\ndefaultEncoder.fromBinObjectId(objectId.id);\n//=\u003e \"WBZTdmxdvBDwrOtV\"\ndefaultEncoder.toBinObjectId(\"WBZTdmxdvBDwrOtV\");\n//=\u003e Uint8Array [88 ... 85]\n\nconst uuid = new Uint8Array([0x6d, ..., 0x9f]);\ndefaultEncoder.fromBinUUID(uuid);\n//=\u003e \"ygtwdVymRMenB4rdSkqHDS\"\ndefaultEncoder.toBinUUID(\"ygtwdVymRMenB4rdSkqHDS\");\n//=\u003e new Uint8Array([0x6d, ..., 0x9f])\n```\n\n### Hex UUIDs and ObjectIds\n\n`Encoder` also supports coversion between the canonical id hex strings and\nBase64:\n\n```javascript\nconst encoder = new Encoder();\n\nconst objectId = new ObjectId();\nconst hex = objectId.toHexString();\n//=\u003e '581653766c5dbc10f0aceb55'\nlet encoded = encoder.fromObjectId(hex);\n//=\u003e 'WBZTdmxdvBDwrOtV'\nlet decoded = encoder.toObjectId(encoded);\n//=\u003e '581653766c5dbc10f0aceb55'\n// or back to binary\ndecoded = encoder.toBinObjectid(encoded);\n// =\u003e Uint8Array [...]\n\nconst uuid = crypto.randomUUID();\n//=\u003e \"6d2bb408-3176-42d3-b473-3d251f19569f\"\nencoded = encoder.fromUUID(uuid);\n//=\u003e \"bSu0CDF2QtO0cz0lHxlWCf\"\ndecoded = encoder.toUUID(encoded);\n//=\u003e \"6d2bb408-3176-42d3-b473-3d251f19569f\"\n```\n\n### Id Encryption\n\nWhile encoding with custom character sets can achieve certain obfurscation, it\nis not a strong encryption. To secure structured ids from business intelligence\nleaks where it really matters, one should use strong encryption algorithms.\nHence, `Encrypter` class provides an interface for encrypting ids into UUID-like\n128-bit values using AES encryption offered by Web Crypto API.\n\n```typescript\nconst encoder = new Encoder();\n// generates 128-bit AES-CRT key to use in our encrypter\nconst key = await Encrypter.generateKey();\nconst encrypter = new Encrypter(key);\nconst objectId = new ObjectId();\nencoder.fromBinObjectId(objectId.id);\n//=\u003e WBZTdmxdvBDwrOtV\nconst encrypted = await encrypter.fromObjectId(objectId.id);\nencoder.fromBinUUID(encrypted);\n//=\u003e zSrTRzGRrRZOVR5_2gbDBd\nconst decrypted = await encrypter.toObjectId(encrypted);\nencoder.fromBinObjectId(decrypted);\n//=\u003e WBZTdmxdvBDwrOtV\n```\n\n## Benchmark\n\n```\n\u003e deno bench --unstable\nbenchmark                                time (avg)             (min … max)       p75       p99      p995\n--------------------------------------------------------------------------- -----------------------------\n[ObjectId Hex to Base64] ObjectId64    1.26 µs/iter     (1.19 µs … 1.67 µs)   1.28 µs   1.67 µs   1.67 µs\nBigInt                                 5.95 µs/iter     (5.86 µs … 6.28 µs)   5.96 µs   6.28 µs   6.28 µs\nbase64-mongo-id                        2.72 µs/iter     (2.56 µs … 4.43 µs)   2.72 µs   4.43 µs   4.43 µs\n\nsummary\n  [ObjectId Hex to Base64] ObjectId64\n   2.15x faster than base64-mongo-id\n   4.71x faster than BigInt\n\n[UUID Hex to Base64] ObjectId64        2.51 µs/iter     (2.25 µs … 3.78 µs)   2.47 µs   3.78 µs   3.78 µs\nuuid-base64                            8.67 µs/iter      (6.5 µs … 3.01 ms)      8 µs   23.8 µs   25.7 µs\n\nsummary\n  [UUID Hex to Base64] ObjectId64\n   3.45x faster than uuid-base64\n\n[UUID Binary] ObjectId64               3.13 µs/iter      (2.1 µs … 4.23 ms)    2.6 µs    8.5 µs   13.6 µs\nid128 ULID                             4.44 µs/iter     (3.1 µs … 17.98 ms)    3.9 µs     12 µs   20.3 µs\nid128 UUID                             43.8 µs/iter      (4.6 µs … 4.16 ms)   54.9 µs    112 µs  141.6 µs\n\nsummary\n  [UUID Binary] ObjectId64\n   1.42x faster than id128 ULID\n   14.01x faster than id128 UUID\n\n[ObjectId Binary] ObjectId64           1.81 µs/iter     (1.39 µs … 4.99 µs)   1.87 µs   4.99 µs   4.99 µs\nBSON                                    4.4 µs/iter       (3.6 µs … 5.1 ms)      4 µs   13.2 µs   19.2 µs\n\nsummary\n  [ObjectId Binary] ObjectId64\n   2.44x faster than BSON\n\n[UUID Encode/Encrypt] Encode UUID      2.36 µs/iter      (2.12 µs … 4.4 µs)   2.16 µs    4.4 µs    4.4 µs\nEncrypt UUID                         209.52 µs/iter    (150.3 µs … 3.59 ms)  209.4 µs  501.6 µs  700.1 µs\n\nsummary\n  [UUID Encode/Encrypt] Encode UUID\n   88.69x faster than Encrypt UUID\n\n[Int Encode/Encrypt] Encode Int      318.29 ns/iter (281.78 ns … 736.37 ns) 296.57 ns 662.18 ns 736.37 ns\nEncrypt Int                          198.17 µs/iter    (156.4 µs … 4.18 ms)  187.9 µs  436.3 µs  605.5 µs\n\nsummary\n  [Int Encode/Encrypt] Encode Int\n   622.62x faster than Encrypt Int\n```\n\n## License\n\nMIT © [Maga D. Zandaqo](http://maga.name)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzandaqo%2Fobjectid64","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzandaqo%2Fobjectid64","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzandaqo%2Fobjectid64/lists"}