Skip to Content
TokenCode Shape

Unreleased changes

These pages document main, which has changes 0.1.2 does not. npm install @evanion/token gives you 0.1.2, documented here. Values on these pages are produced by running the current source on every build.

Code shape

To mint an @evanion/token code longer or shorter than a pickup code, or grouped differently, you pass length, chunkSize and separator to createToken.

The Problem: One Size Doesn’t Fit All

A short, 8-character code is perfect for a pickup order—it’s easy to read and type. But for a high-value gift card, an 8-character code is too easy to guess or collide. You need a longer, more secure identifier that still feels “human-readable” through proper chunking.

Conversely, a “counter code” meant to be spoken aloud might need a very specific shape—perhaps two short words separated by a space—to reduce miscommunication.

Solution: Custom Token Shapes

createToken allows you to define the exact geometry of your codes. By adjusting the length and chunking, you can balance security (entropy) with usability.

For a gift card, you might want more characters to reduce the risk of collisions:

const = ({ : 16, : 4 }); .()..; // -> 19 .; // -> 75

In this example, giftCard draws 15 random characters and appends a check character. With the default 32-character dictionary, this provides significant entropy (75 bits). Using a chunkSize of 4 creates a visually organized code with three hyphens, resulting in a 19-character value.

Shape Options Reference

OptionTypeDefaultMeaning
lengthnumber8Total characters, including the check character.
chunkSizenumber4Characters per chunk; must divide length evenly.
separatorstring'-'Character used between chunks and after a prefix.
dictionarystring(Default alphabet)The set of characters used to generate the code.

createToken validates these options once during instance creation. Every code minted by that instance is guaranteed to match this shape.

Creating “Spoken” Codes

If you need a code that is easy to call out across a room, you can use a space as a separator and a smaller chunk size. This turns a string of characters into something that reads like two short words:

const = ({ : 6, : 3, : ' ' }); const { } = .(); .; // -> 7 .(3); // -> ' ' .().; // -> true .(.(' ', '-')).; // -> false

Because validate is tied to the instance that created the code, counterCode.validate knows to strip spaces rather than hyphens.

Invalid Shapes and InvalidShapeError

Not every combination of options is mathematically possible. createToken will throw an InvalidShapeError if the shape is invalid. This is designed to stop your application at start-up rather than failing silently at runtime.

import { , } from '@evanion/token'; import type { TokenOptions } from '@evanion/token'; /** The shape error `createToken` throws for `options`, if it throws one. */ function (: TokenOptions): | undefined { try { (); } catch () { if ( instanceof ) return ; throw ; } return ; } ({ : 10, : 5 }); // -> undefined ({ : 10, : 4 })?.; // -> 'chunk-size-indivisible' ({ : 10, : 4 })?.; // -> 'Token chunkSize must divide length, or the last chunk is shorter than the rest; 4 does not divide 10.' ({ : 12, : 4 }); // -> undefined ({ : '0123456789abcde-' })?.; // -> 'separator-in-dictionary' ({ : 'a' })?.; // -> 'separator-in-dictionary' ({ : 'a' })?.; // -> 8

Common Shape Errors

reasonCauseFix
lengthlength is not an integer or is below 2.Set a valid positive integer.
chunk-sizechunkSize is not an integer or is below 1.Set a valid positive integer.
chunk-size-indivisiblechunkSize does not divide length evenly.Adjust either length or chunkSize.
separator-emptyseparator is an empty string.Provide a separator character.
separator-in-dictionaryseparator is also a character in the dictionary.Choose a separator that doesn’t appear in the alphabet.

If the separator is also in the dictionary, validate would be unable to strip it without accidentally removing part of the code’s body, which is why this is forbidden.

Try a Token Shape

You can experiment with different shapes and dictionaries using the interactive tool below.

a4kp-9mxa

Say it as
Drawn from

35 bits, so a collision is even odds at 218,000 codes.

Adjust the length, chunking, and alphabet to see how it affects the code’s entropy and collision probability.

Draw Codes from Another Dictionary

Every example so far has used the default 32-character alphabet. The alphabet shows how to provide your own dictionary to createToken and the rules that a custom alphabet must follow.

Last updated on