anyid
TypeScript icon, indicating that this package has built-in type declarations

1.0.7 • Public • Published

AnyID - ID generator for node.js

npm version travis ci Coverage Status Try on Runkit

Verified on node.js v6, v8, v10 and v11

Table of Contents

Introduction

AnyID is a simple and flexible API to generate various kinds of string ID / code.

The generated ID is compounded by sections with optional delimiter. Each section is encoded into specificed chars and may have fix length.

sdk3ksxjcs-JEDke3x8F-sldle34CZs
^^^^^^^^^^          ^
│                   │
└ section           └ delimiter

A section may contain one or more values. Multiple values are concatenated into bit stream before encoded.

┌───────────────────────┬───────────────┬──────────────────┐
│  timestamp (41 bits)  │ seq (12 bits) │ worker (10 bits) │
└───────────────────────┴───────────────┴──────────────────┘

Use it in your code:

import {anyid} from 'anyid';
const ids = anyid().encode('Aa0').length(21).random();
console.log(ids.id());

If you aren't using ES6, this is the way to require it:

var anyid = require('anyid').anyid;

>>> Try it in your browser. <<<

Encode

Encode with given charset:

encode(charsetstring)

Charset is specified by simple letter:

  • A - Alphabet in upper case
  • a - Alphabet in lower case
  • 0 - Numeric

Individual letters can be exclude by followed after -, be appended by followed after +.

Example:

  • Aa0 = A-Z a-z 0-9
  • 0A-IO = 0-9 A-Z, excludes I and O
  • 0+ABCDEF = 0-9 A-F
  • A+012-IO = A-Z 0 1 2, excludes I and O

Section and Delimiter

A section accepts an AnyId object as parameter. For ID containing single section, section function is not used.

section( anyidAnyId )

Section length can be fixed or variant. When length is specified, section will be trimmed or padded at beginning side.

length(nnumber)

For some kinds of value, e.g. random, length must be given.

Hint What length will be if not specified?

b: value bytes
a: charset size
length ≧ logₐ256ᵇ = log₂ 256ᵇ / log₂ a = 8b / log₂ a

For example:

Value is 4 bytes UInt32, charset is A-Za-z0-9 which has 62 characters. 8 * 4 / log₂ 62 = 5.37. Maximum length will be 6.

Delimiter can be put between sections. It's output as is and never be encoded.

delimiter( sstring )

Value

AnyID supports several kinds of value:

  • random
  • timestamp
  • sequence
  • fix value
  • function result
  • variable

Value is either non-negative integer (UInt32) or Buffer (byte array).

A section may have more than one values. Values will be concatenated as bit stream before encoded.

You can use bits to specify the bit width of a value. Higher bits will be discard if value has more bits than desired.

bits( nnumber )

Random

Generate value by random. Length or bits must be specified.

random()

Internally it uses crypto.randomBytes() to generate random.

Hint The probability of duplicates in n random IDs is:

p(n) ≈ n²/(2*C^L)

Where L is the length of random id, C is the size of encode charset.

For example: using anyid().encode('Aa0').length(21).random() to generate randome ID, L is 21 and C is 62. Then p(n) ≈ n²/(2*62^21). It has lower probability of duplicates then type 4 (random) UUID.

Timestamp

Use current timestamp as value.

time( unitstring = 'ms' )

Unit can be ms, s, m, h, d.

By default, timestamp value is since UNIX epoch time. You can overwrite it to a recent date to save some bits.

since( tDate )

Sequence

Sequence increases everytime an ID is generated.

seq()

By default, sequence starts from 0. You can set it to any non-negative integer.

startWith( nnumber )

Sequence will be reset after it reaches max value. It can not exceed 2^32 (max value represented by UInt32).

max( nnumber )

Or, let it reset when timestamp changes:

resetByTime()

To use resetByTime, there must be a timestamp value in the ID.

Fixed value

fixed( nnumber | Buffer )

Value is either non-negative integer (UInt32) or Buffer (byte array).

Function result

Similar to fix value, but the value is returned by a function which is called an ID is to be generated.

of( f: () => number | Buffer )

Variable

Similar to fix value, but the value is given in id function call.

variable( name?: string )

When there is only one variable used in ID generator, the name can be omitted in variable() and the value is directly passing in id function call:

id( v: number | Buffer )

When there are multiple variables used in ID generator, the values need to be passing in id in an object:

id( v: {[name: string]: number | Buffer} )

Read example below to check how it's used.

Examples

Single section, random value

This id has essence the same low probability of a clash as type 4 (random) UUID:

const ids = anyid().encode('Aa0').length(21).random()
const id  = ids.id();
1LrKcmd0uk1Ma8szUxtda

Multiple sections, fix prefix and timestamp

const ids = anyid()
  .encode('0A-IO')
  .section( anyid().fixed(process.pid) )
  .delimiter('-')
  .section( anyid().time() );

It uses human friendly charset: I and O are excluded because of similarity to 1 and 0.

008CL-00TYMZS0P3

Sequence and bit stream concatenation

It's Twitter Snowflake style ID with timestamp, sequence and worker.

const ids = anyid()
  .encode('0')
  .bits(41).time().since(new Date('2016-7-1'))
  .bits(12).seq().resetByTime();
  .bits(10).fix(workerId);

Timestamp is since 2016-7-1. Sequence is reset every millisecond.

071243223959339218

Function value

ID contains second and nanosecond. Nanosecond is retrieved by a function.

const nanotime = () => process.hrtime()[1];
 
const ids = anyid()
  .encode('Aa0')
  .section( anyid().time('s') )
  .delimiter('+')
  .section( anyid().of(nanotime) );
BlX6bX+j3Uz0

Use different charset in sections

The ID has default charset A-IO. The second section uses charset 0.

const ids = anyid()
  .encode('A-IO')
  .section( anyid().length(3).random() )
  .delimiter(' ')
  .section( anyid().encode('0').length(3).random() )
  .delimiter(' ')
  .section( anyid().length(3).random() );
HQX 552 ATC

Single variable

const ids = anyid()
  .encode('Aa0')
  .section( anyid().variable() )
  .delimiter('-')
  .section( anyid().time() );
 
const id = ids(Buffer.from('user-xxx'));
KFLnaOrolmA-AAZ28TmMo

Multiple variables

const ids = anyid()
  .encode('Aa0')
  .section( anyid().variable('countryId') )
  .delimiter('-')
  .section( anyid().variable('userId') )
  .delimiter('-')
  .section( anyid().length(5).random() );
 
const id = ids.id({ countryId: 86, userId: 635023 });
AAABY-ACpMT-EBwQJ

Dependents (14)

Package Sidebar

Install

npm i anyid

Weekly Downloads

936

Version

1.0.7

License

MIT

Unpacked Size

52.2 kB

Total Files

36

Last publish

Collaborators

  • aleung