Rando
Rando is a library for generating identifiers. IDs are random and universally unique by default. Options can be modified to fit a wide variety of requirements. In a node environment, randomness is provided by the node:crypto
module. In a browser environment, randomness is provided by the Web Crypto API.
Install
npm i @balancer-team/rando
Usage
Import the rando class and create an instance. The instance generates IDs with the generate()
method.
import { Rando } from '@balancer-team/rando'
const rando = new Rando()
rando.generate() // => "Jb46bM8xM3mhDLnpQrwNvN"
Customizing the Length
If you want a longer random string, for example if you want extra security for an API key, it's easy to modify the length. The example below generates a 46-character ID with over 256 bits of entropy:
const rando = new Rando({ length: 46 })
rando.generate() //=> "X5533mwXPH6V2nMN5548t1vkFVN4RTJqM89JNQcbVjmt1G"
Sortable IDs
Rando can generate sortable IDs where the beginning of the ID is an encoded timestamp using the given alphabet
. Rando will evaluate the alphabet
length and automatically determine how many characters are required to encode a timestamp at millisecond precision. The length
must be sufficient for millisecond precision. Refer to the table below for guidance on the length needed to support a given year with a given alphabet base.
const rando = new Rando({ sortable: true })
rando.generate()
// Output:
//
// "13DNYFr2DBJvhWfWCs58Nb"
// |------||------------|
// Sortable Random
// Segment Segment
Sortable IDs can be decoded to return a date. Note that the instance doing the decoding must have the same options as the instance that generated it.
rando.getDate('13DNYFr2DBJvhWfWCs58Nb').toISOString() //=> "2025-02-25T13:11:45.061Z"
All Options
Rando instances can be extensively customized to generate the perfect identifier for your requirements. Here's the type definition of all available options, with details below:
type RandoOptions = {
alphabet?: string
length?: number
sortable?: boolean
supportDate?: Date
}
Property | Default | Description |
---|---|---|
alphabet | BASE_50 | A string of characters to use to generate your IDs. Each character must be unique. The default base 50 alphabet excludes vowels and ambiguous characters. |
length | 22 | The length of the ID. By default, the length is 22 which provides 124 bits of entropy, slightly more than a UUIDv4. |
sortable | false | Makes the ID sortable when set to true . The leading characters encode a timestamp at millisecond precision. |
supportDate | '4000' | Allows you to specify a target date for the sortable segment. See below for additional details. |
Special Considerations for Sortable IDs
The length
and base of the alphabet
together determine how long the sortable segment must be for millisecond precision. If the length
is too short, Rando will throw an error when instantiated. The supportDate
property allows you to specify a target date for the sortable segment to support. The sortable segment will be left-padded to support the target date with a consistent overall length.
Note that making an ID sortable will reduce the number of random characters in the ID. If you console.log
the instance, you will see several helpful properties such as randomBits
that can help you determine whether or not the ID meets your requirements.
const rando = new Rando({ sortable: true })
// Output:
//
// Rando {
// alphabet: '123456789BCDFGHJKLMNPQRSTVWXYZbcdfghjkmnpqrstvwxyz',
// length: 22,
// randomLength: 13,
// base: 50,
// randomBits: 73.37013046707142,
// randomLimit: 1.2207031249999986e+22,
// sortable: true,
// supportDate: 4000-01-01T00:00:00.000Z,
// sortableLength: 9,
// sortableLimit: +063862-01-25T10:13:20.000Z
// }
Presets
Rando comes with a few presets to make it easy to generate IDs for common use cases.
import { rando, sorto, locker, sesame, pinto } from '@balancer-team/rando/presets'
rando.generate() //=> "7kFD8XHYp1JdXXzYsxRvXT"
sorto.generate() //=> "13DNYDsRBvc6TQ2HwHh1GW"
locker.generate() //=> "5Myvnv4BQm7rDhz3zntYGMXf9Srr71z7wFwF1SSYMQVvQQ"
sesame.generate() //=> "E@MvHJG4JbA$o{8ll0AK"
pinto.generate() //=> "368230"
rando
Default, like a compact UUIDv4.sorto
Sortable string followed by a random string, like a compact UUIDv7.locker
Long string with over 256 bits of entropy, suitable for API keys.sesame
Secure password with over 128 bits of entropy.pinto
Numerical 6-digit pin for verification codes.
Guidance for Sortable IDs
The following table is a guide for the length needed to support at least the year 3000 with a given alphabet base.
Base | Length | Max Year |
---|---|---|
2 | 46 | 4199 |
3 | 29 | 4144 |
4 | 23 | 4199 |
5 | 20 | 4992 |
6 | 18 | 5188 |
7 | 17 | 9341 |
8 | 16 | 10889 |
9 | 15 | 8494 |
10 | 14 | 5138 |
11 | 14 | 14003 |
12 | 13 | 5360 |
13 | 13 | 11567 |
14 | 13 | 27121 |
15 | 12 | 6081 |
16 | 12 | 10889 |
17 | 12 | 20432 |
18 | 11 | 4006 |
19 | 11 | 5661 |
20 | 11 | 8459 |
21 | 11 | 13069 |
22 | 11 | 20486 |
23 | 11 | 32163 |
24 | 11 | 50190 |
25 | 10 | 4992 |
26 | 10 | 6443 |
27 | 10 | 8494 |
28 | 10 | 11356 |
29 | 10 | 15301 |
30 | 10 | 20681 |
31 | 10 | 27942 |
32 | 10 | 37648 |
33 | 10 | 50503 |
34 | 10 | 67387 |
35 | 9 | 4467 |
36 | 9 | 5188 |
37 | 9 | 6088 |
38 | 9 | 7205 |
39 | 9 | 8584 |
40 | 9 | 10277 |
41 | 9 | 12344 |
42 | 9 | 14856 |
43 | 9 | 17896 |
44 | 9 | 21557 |
45 | 9 | 25948 |
46 | 9 | 31193 |
47 | 9 | 37433 |
48 | 9 | 44832 |
49 | 9 | 53572 |
50 | 9 | 63862 |
51 | 9 | 75936 |
52 | 9 | 90061 |
53 | 9 | 106535 |
54 | 8 | 4261 |
55 | 8 | 4623 |
56 | 8 | 5034 |
57 | 8 | 5501 |
58 | 8 | 6028 |
59 | 8 | 6622 |
60 | 8 | 7292 |
61 | 8 | 8044 |
62 | 8 | 8888 |
63 | 8 | 9833 |
64 | 8 | 10889 |