Skip to Content
TokenCode Shape

Code shape

@evanion/token 0.1.0 and its patch releases up to 0.1.2, the version on npm. Values on this page were produced by running the source at 77650ee, a later commit than the 0.1.0 tag, and are not re-executed.

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.

The interactive example this release showed here runs against the current source, so it is on the same page under /next/ and not on this one. 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