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

@balancer-team/rando

v5.0.6

Published

Generate identifiers with Rando.

Downloads

53

Readme

Rando

Rando is a tool for generating identifiers. By default, rando() generates a cryptographically random, universally unique ID. Options can be modified to fit a wide variety of requirements.

Install

npm i @balancer-team/rando

Usage

Import the rando class and create an instance. The instance generates IDs with the generate() method. By default, IDs are 22 characters long, use a base 58 alphabet, and have 128 bits of entropy. The default settings provide a good balance of entropy, human-readability, and URL safety.

import { Rando } from '@balancer-team/rando'

const rando = new Rando()
rando.generate() // => "ogm3Yzf4NnSKJsDnL8ma8X"

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 44-character ID with over 256 bits of entropy:

const rando = new Rando({ length: 44 })
rando.generate() //=> "NfHRpTLJkjXcKmprjcpQ4UgRfL4KKEGoSrBLytf5RD44"

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. If the length isn't sufficient for millisecond precision, the precision will be reduced as needed.

const rando = new Rando({ sortable: true })
rando.generate()

// Output:
//
// "1nN6oZkdAnxQck8bPqUCzG"
//  |------||------------|
//  Sortable    Random
//  Segment     Segment

Sortable IDs can easily be decoded to return a date object. Note that the instance doing the decoding must have the same options set as the instance that generated it.

rando.getDate('1nN6oZkdAnxQck8bPqUCzG').toISOString() //=> 2024-09-21T17:38:44.418Z

Signed IDs

You can add a signature to the end of an ID to verify its authenticity. This is useful for preventing tampering with the ID and stopping brute-force attempts at guessing IDs, since verification can be handled by your server instead of your database. The signature is generated using the HMAC algorithm with the SHA-256 hash function. The signature is encoded using the same alphabet as the random segment, and the length of the signature will vary depending on the base of the alphabet. Longer alphabets will result in shorter signatures.

// Generate the ID and sign it
const rando = new Rando({ secret: 'secret' }) // Use a secure secret, of course
const id = rando.generate() //=> "2VRw9zT8EHVFdxnzSXremp"
const signed = rando.sign(id) //=> "2VRw9zT8EHVFdxnzSXrempDPvgBzGv9RiGbLnUnQ8X2qPGbuYUzH1exnSnfKFVWrXM"

// Verify the signature
const verified = rando.verify(signed) //=> "2VRw9zT8EHVFdxnzSXremp"

// Handling the result
if (verified) {
  console.log(verified) //=> "2VRw9zT8EHVFdxnzSXremp"
} else {
  console.log(verified) //=> null
}

The verify method will return the original ID if the signature is valid, or null if the signature is invalid.

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
  secret?: string
}

| Property | Default | Description | | ------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | alphabet | BASE_58 | A string of characters to use to generate your IDs. By default, the base 58 alphabet is used for a good balance of human-readability, URL safety, and entropy. | | length | 22 | The length of the ID. By default, the length is 22 which provides 128 bits of entropy with a base 58 alphabet. | | sortable | false | Makes the ID sortable. With the default base 58 alphabet, the first 8 characters are used to encode a timestamp at millisecond precision. | | supportDate | 3000-01-01 | Allows you to specify a target date for the sortable segment to support. See below for additional details. | | secret | undefined | Provide a secret for the sign and verify methods. The secret property can be changed after the instance is created, allowing you to set secrets even on presets. A good signing secret should be at least 32 characters long. |

Special Considerations for Sortable IDs

The length and base of the alphabet together determine how long the sortable segment must be to support millisecond precision. If the length isn't long enough to support millisecond precision, the timestamp precision will be reduced as needed. 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 as needed.

Note that making an ID sortable will reduce the number of random characters in the ID. If you console.log the Rando instance, you will see several helpful properties that can help you determine whether or not the ID meets your requirements.

const rando = new Rando({ sortable: true, secret: 'secret' })

//=> Output
// Rando {
//   alphabet: '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz',
//   length: 22,
//   randomLength: 14,
//   base: 58,
//   randomBits: 82.01173393178601,
//   randomLimit: 4.875194084160305e+24,
//   sortable: true,
//   supportDate: 3000-01-01T05:00:00.000Z,
//   sortableLength: 8,
//   sortableLimit: 6028-02-27T14:15:18.016Z,
//   sortableTrim: 0,
//   sortableResolution: '1 millisecond',
//   sortableFullLength: 8,
//   signatureFullLength: 44,
//   secret: 'secret'
// }

Presets

Rando comes with a few presets to make it easy to generate IDs for common use cases.

import { rando, particle, locker, pinto, slug } from '@balancer-team/rando/presets'

rando.generate() //=> "ogm3Yzf4NnSKJsDnL8ma8X"
particle.generate() //=> "1nMK3pu9oQ8ff2jVutn5PR"
locker.generate() //=> "KExaEVwFiZ5XL7339yjauuW2VAD2BrzBP5BPT8GWXbtX"
pinto.generate() //=> "368230"
slug.generate() //=> "gD75nv"
  • rando Default settings with over 128 bits of entropy, like a compact UUIDv4.
  • particle Sortable ID with over 80 bits of entropy, like a compact UUIDv7.
  • locker Long string with over 256 bits of entropy, suitable for API keys.
  • pinto Numerical 6-digit pin for email or phone verification.
  • slug Short, no vowels, over 32 bits of entropy.

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. The table assumes that the timestamp supports millisecond precision.

| Base | Length | Max Year | | ---- | ------ | -------- | | 2 | 45 | 3084 | | 3 | 29 | 4144 | | 4 | 23 | 4199 | | 5 | 20 | 4992 | | 6 | 18 | 5188 | | 7 | 16 | 3023 | | 8 | 15 | 3084 | | 9 | 15 | 8494 | | 10 | 14 | 5138 | | 11 | 13 | 3063 | | 12 | 13 | 5360 | | 13 | 13 | 11567 | | 14 | 12 | 3766 | | 15 | 12 | 6081 | | 16 | 12 | 10889 | | 17 | 11 | 3056 | | 18 | 11 | 4006 | | 19 | 11 | 5661 | | 20 | 11 | 8459 | | 21 | 11 | 13069 | | 22 | 11 | 20486 | | 23 | 10 | 3282 | | 24 | 10 | 3979 | | 25 | 10 | 4992 | | 26 | 10 | 6443 | | 27 | 10 | 8494 | | 28 | 10 | 11356 | | 29 | 10 | 15301 | | 30 | 10 | 20681 | | 31 | 10 | 27942 | | 32 | 9 | 3084 | | 33 | 9 | 3440 | | 34 | 9 | 3894 | | 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 | 8 | 3023 | | 50 | 8 | 3207 | | 51 | 8 | 3420 | | 52 | 8 | 3664 | | 53 | 8 | 3942 | | 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 |