Socket
Socket
Sign inDemoInstall

nanoid

Package Overview
Dependencies
0
Maintainers
1
Versions
100
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 2.1.11 to 3.0.0

async/index.cjs

89

async/index.browser.js

@@ -1,37 +0,68 @@

// This file replaces `async/index.js` in bundlers like webpack or Rollup,
// according to `browser` config in `package.json`.
let customAlphabet = (alphabet, size) => {
// First, a bitmask is necessary to generate the ID. The bitmask makes bytes
// values closer to the alphabet size. The bitmask calculates the closest
// `2^31 - 1` number, which exceeds the alphabet size.
// For example, the bitmask for the alphabet size 30 is 31 (00011111).
// `Math.clz32` is not used, because it is not available in browsers.
let mask = (2 << Math.log(alphabet.length - 1) / Math.LN2) - 1
// Though, the bitmask solution is not perfect since the bytes exceeding
// the alphabet size are refused. Therefore, to reliably generate the ID,
// the random bytes redundancy has to be satisfied.
var crypto = self.crypto || self.msCrypto
// Note: every hardware random generator call is performance expensive,
// because the system call for entropy collection takes a lot of time.
// So, to avoid additional system calls, extra bytes are requested in advance.
// This alphabet uses a-z A-Z 0-9 _- symbols.
// Symbols are generated for smaller size.
// -_zyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBA
var url = '-_'
// Loop from 36 to 0 (from z to a and 9 to 0 in Base36).
var i = 36
while (i--) {
// 36 is radix. Number.prototype.toString(36) returns number
// in Base36 representation. Base36 is like hex, but it uses 0–9 and a-z.
url += i.toString(36)
// Next, a step determines how many random bytes to generate.
// The number of random bytes gets decided upon the ID size, mask,
// alphabet size, and magic number 1.6 (using 1.6 peaks at performance
// according to benchmarks).
// `-~f => Math.ceil(f)` if f is a float
// `-~i => i + 1` if i is an integer
let step = -~(1.6 * mask * size / alphabet.length)
return () => {
let id = ''
while (true) {
let bytes = crypto.getRandomValues(new Uint8Array(step))
// A compact alternative for `for (var i = 0; i < step; i++)`.
let i = step
while (i--) {
// Adding `|| ''` refuses a random byte that exceeds the alphabet size.
id += alphabet[bytes[i] & mask] || ''
// `id.length + 1 === size` is a more compact option.
if (id.length === +size) return id
}
}
}
}
// Loop from 36 to 10 (from Z to A in Base36).
i = 36
while (i-- - 10) {
url += i.toString(36).toUpperCase()
}
module.exports = function (size) {
var id = ''
var bytes = crypto.getRandomValues(new Uint8Array(size || 21))
i = size || 21
let nanoid = (size = 21) => {
let id = ''
let bytes = crypto.getRandomValues(new Uint8Array(size))
// Compact alternative for `for (var i = 0; i < size; i++)`
while (i--) {
// We can’t use bytes bigger than the alphabet. 63 is 00111111 bitmask.
// This mask reduces random byte 0-255 to 0-63 values.
// There is no need in `|| ''` and `* 1.6` hacks in here,
// because bitmask trim bytes exact to alphabet size.
id += url[bytes[i] & 63]
// A compact alternative for `for (var i = 0; i < step; i++)`.
while (size--) {
// It is incorrect to use bytes exceeding the alphabet size.
// The following mask reduces the random byte in the 0-255 value
// range to the 0-63 value range. Therefore, adding hacks, such
// as empty string fallback or magic numbers, is unneccessary because
// the bitmask trims bytes down to the alphabet size.
let byte = bytes[size] & 63
if (byte < 36) {
// `0-9a-z`
id += byte.toString(36)
} else if (byte < 62) {
// `A-Z`
id += (byte - 26).toString(36).toUpperCase()
} else if (byte < 63) {
id += '_'
} else {
id += '-'
}
}
return Promise.resolve(id)
}
export { nanoid, customAlphabet }

@@ -1,37 +0,69 @@

var random = require('./random')
var url = require('../url')
import crypto from 'crypto'
/**
* Generate secure URL-friendly unique ID. Non-blocking version.
*
* By default, ID will have 21 symbols to have a collision probability similar
* to UUID v4.
*
* @param {number} [size=21] The number of symbols in ID.
*
* @return {Promise} Promise with random string.
*
* @example
* const nanoidAsync = require('nanoid/async')
* nanoidAsync.then(id => {
* model.id = id
* })
*
* @name async
* @function
*/
module.exports = function (size) {
size = size || 21
return random(size).then(function (bytes) {
var id = ''
// Compact alternative for `for (var i = 0; i < size; i++)`
while (size--) {
// We can’t use bytes bigger than the alphabet. 63 is 00111111 bitmask.
// This mask reduces random byte 0-255 to 0-63 values.
// There is no need in `|| ''` and `* 1.6` hacks in here,
// because bitmask trim bytes exact to alphabet size.
id += url[bytes[size] & 63]
import { urlAlphabet } from '../index.js'
// `crypto.randomFill()` is a little faster than `crypto.randomBytes()`,
// because it is possible to use in combination with `Buffer.allocUnsafe()`.
let random = bytes => new Promise((resolve, reject) => {
// `Buffer.allocUnsafe()` is faster because it doesn’t flush the memory.
// Memory flushing is unnecessary since the buffer allocation itself resets
// the memory with the new bytes.
crypto.randomFill(Buffer.allocUnsafe(bytes), (err, buf) => {
if (err) {
reject(err)
} else {
resolve(buf)
}
return id
})
})
let customAlphabet = (alphabet, size) => {
// First, a bitmask is necessary to generate the ID. The bitmask makes bytes
// values closer to the alphabet size. The bitmask calculates the closest
// `2^31 - 1` number, which exceeds the alphabet size.
// For example, the bitmask for the alphabet size 30 is 31 (00011111).
let mask = (2 << 31 - Math.clz32((alphabet.length - 1) | 1)) - 1
// Though, the bitmask solution is not perfect since the bytes exceeding
// the alphabet size are refused. Therefore, to reliably generate the ID,
// the random bytes redundancy has to be satisfied.
// Note: every hardware random generator call is performance expensive,
// because the system call for entropy collection takes a lot of time.
// So, to avoid additional system calls, extra bytes are requested in advance.
// Next, a step determines how many random bytes to generate.
// The number of random bytes gets decided upon the ID size, mask,
// alphabet size, and magic number 1.6 (using 1.6 peaks at performance
// according to benchmarks).
let step = Math.ceil(1.6 * mask * size / alphabet.length)
let tick = id => random(step).then(bytes => {
// A compact alternative for `for (var i = 0; i < step; i++)`.
let i = step
while (i--) {
// Adding `|| ''` refuses a random byte that exceeds the alphabet size.
id += alphabet[bytes[i] & mask] || ''
// `id.length + 1 === size` is a more compact option.
if (id.length === +size) return id
}
return tick(id)
})
return () => tick('')
}
let nanoid = (size = 21) => random(size).then(bytes => {
let id = ''
// A compact alternative for `for (var i = 0; i < step; i++)`.
while (size--) {
// It is incorrect to use bytes exceeding the alphabet size.
// The following mask reduces the random byte in the 0-255 value
// range to the 0-63 value range. Therefore, adding hacks, such
// as empty string fallback or magic numbers, is unneccessary because
// the bitmask trims bytes down to the alphabet size.
id += urlAlphabet[bytes[size] & 63]
}
return id
})
export { nanoid, customAlphabet }
# Change Log
This project adheres to [Semantic Versioning](http://semver.org/).
## 3.0
Migration guide: <https://github.com/ai/nanoid/releases/tag/3.0.0>
* Move to ES2016 syntax. You need to use Babel for IE 11.
* Move to named exports `import { nanoid } from 'nanoid'`.
* Move `import url from 'nanoid/url'` to `import { urlAlphabet } from 'nanoid'`.
* Replace `format()` to `customRandom()`.
* Replace `generate()` to `customAlphabet()`.
* Remove `async/format`.
* Remove React Native support for `nanoid/async`.
* Add `nanoid.js` to use directly in browser from CDN.
* Add TypeScript type definitions.
* Add ES modules support for bundlers, Node.js, and React Native.
* Fix React Native support.
* Reduce size.
* Improve docs (by Dair Aidarkhanov).
## 2.1.11

@@ -5,0 +21,0 @@ * Reduce size (by Anton Evzhakov).

@@ -5,12 +5,21 @@ // This file replaces `index.js` in bundlers like webpack or Rollup,

if (process.env.NODE_ENV !== 'production') {
// All bundlers will remove this block in production bundle
if (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') {
// All bundlers will remove this block in the production bundle.
if (
typeof navigator !== 'undefined' &&
navigator.product === 'ReactNative' &&
!self.crypto
) {
throw new Error(
'React Native does not have a built-in secure random generator. ' +
'If you don’t need unpredictable IDs, you can use `nanoid/non-secure`. ' +
'For secure ID install `expo-random` locally and use `nanoid/async`.'
'For secure IDs, import `react-native-get-random-values` before Nano ID.'
)
}
if (typeof self === 'undefined' || (!self.crypto && !self.msCrypto)) {
if (typeof self !== 'undefined' && self.msCrypto && !self.crypto) {
throw new Error(
'Add self.crypto = self.msCrypto before Nano ID to fix IE 11 support'
)
}
if (typeof self === 'undefined' || !self.crypto) {
throw new Error(
'Your browser does not have secure random generator. ' +

@@ -22,35 +31,78 @@ 'If you don’t need unpredictable IDs, you can use nanoid/non-secure.'

var crypto = self.crypto || self.msCrypto
// This alphabet uses `A-Za-z0-9_-` symbols. The genetic algorithm helped
// optimize the gzip compression for this alphabet.
let urlAlphabet =
'ModuleSymbhasOwnPr-0123456789ABCDEFGHNRVfgctiUvz_KqYTJkLxpZXIjQW'
// This alphabet uses a-z A-Z 0-9 _- symbols.
// Symbols are generated for smaller size.
// -_zyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBA
var url = '-_'
// Loop from 36 to 0 (from z to a and 9 to 0 in Base36).
var i = 36
while (i--) {
// 36 is radix. Number.prototype.toString(36) returns number
// in Base36 representation. Base36 is like hex, but it uses 0–9 and a-z.
url += i.toString(36)
let random = bytes => crypto.getRandomValues(new Uint8Array(bytes))
let customRandom = (alphabet, size, getRandom) => {
// First, a bitmask is necessary to generate the ID. The bitmask makes bytes
// values closer to the alphabet size. The bitmask calculates the closest
// `2^31 - 1` number, which exceeds the alphabet size.
// For example, the bitmask for the alphabet size 30 is 31 (00011111).
// `Math.clz32` is not used, because it is not available in browsers.
let mask = (2 << Math.log(alphabet.length - 1) / Math.LN2) - 1
// Though, the bitmask solution is not perfect since the bytes exceeding
// the alphabet size are refused. Therefore, to reliably generate the ID,
// the random bytes redundancy has to be satisfied.
// Note: every hardware random generator call is performance expensive,
// because the system call for entropy collection takes a lot of time.
// So, to avoid additional system calls, extra bytes are requested in advance.
// Next, a step determines how many random bytes to generate.
// The number of random bytes gets decided upon the ID size, mask,
// alphabet size, and magic number 1.6 (using 1.6 peaks at performance
// according to benchmarks).
// `-~f => Math.ceil(f)` if f is a float
// `-~i => i + 1` if i is an integer
let step = -~(1.6 * mask * size / alphabet.length)
return () => {
let id = ''
while (true) {
let bytes = getRandom(step)
// A compact alternative for `for (var i = 0; i < step; i++)`.
let j = step
while (j--) {
// Adding `|| ''` refuses a random byte that exceeds the alphabet size.
id += alphabet[bytes[j] & mask] || ''
// `id.length + 1 === size` is a more compact option.
if (id.length === +size) return id
}
}
}
}
// Loop from 36 to 10 (from Z to A in Base36).
i = 36
while (i-- - 10) {
url += i.toString(36).toUpperCase()
}
module.exports = function (size) {
var id = ''
var bytes = crypto.getRandomValues(new Uint8Array(size || 21))
i = size || 21
let customAlphabet = (alphabet, size) => customRandom(alphabet, size, random)
// Compact alternative for `for (var i = 0; i < size; i++)`
while (i--) {
// We can’t use bytes bigger than the alphabet. 63 is 00111111 bitmask.
// This mask reduces random byte 0-255 to 0-63 values.
// There is no need in `|| ''` and `* 1.6` hacks in here,
// because bitmask trim bytes exact to alphabet size.
id += url[bytes[i] & 63]
let nanoid = (size = 21) => {
let id = ''
let bytes = crypto.getRandomValues(new Uint8Array(size))
// A compact alternative for `for (var i = 0; i < step; i++)`.
while (size--) {
// It is incorrect to use bytes exceeding the alphabet size.
// The following mask reduces the random byte in the 0-255 value
// range to the 0-63 value range. Therefore, adding hacks, such
// as empty string fallback or magic numbers, is unneccessary because
// the bitmask trims bytes down to the alphabet size.
let byte = bytes[size] & 63
if (byte < 36) {
// `0-9a-z`
id += byte.toString(36)
} else if (byte < 62) {
// `A-Z`
id += (byte - 26).toString(36).toUpperCase()
} else if (byte < 63) {
id += '_'
} else {
id += '-'
}
}
return id
}
export { nanoid, customAlphabet, customRandom, urlAlphabet, random }

@@ -1,34 +0,74 @@

var random = require('./random')
var url = require('./url')
import crypto from 'crypto'
/**
* Generate secure URL-friendly unique ID.
*
* By default, ID will have 21 symbols to have a collision probability similar
* to UUID v4.
*
* @param {number} [size=21] The number of symbols in ID.
*
* @return {string} Random string.
*
* @example
* const nanoid = require('nanoid')
* model.id = nanoid() //=> "Uakgb_J5m9g-0JDMbcJqL"
*
* @name nanoid
* @function
*/
module.exports = function (size) {
size = size || 21
var bytes = random(size)
var id = ''
// Compact alternative for `for (var i = 0; i < size; i++)`
let urlAlphabet =
'_-0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
// We reuse buffers with the same size to avoid memory fragmentations
// for better performance.
let buffers = { }
let random = bytes => {
let buffer = buffers[bytes]
if (!buffer) {
// `Buffer.allocUnsafe()` is faster because it doesn’t flush the memory.
// Memory flushing is unnecessary since the buffer allocation itself resets
// the memory with the new bytes.
buffer = Buffer.allocUnsafe(bytes)
if (bytes <= 255) buffers[bytes] = buffer
}
return crypto.randomFillSync(buffer)
}
let customRandom = (alphabet, size, getRandom) => {
// First, a bitmask is necessary to generate the ID. The bitmask makes bytes
// values closer to the alphabet size. The bitmask calculates the closest
// `2^31 - 1` number, which exceeds the alphabet size.
// For example, the bitmask for the alphabet size 30 is 31 (00011111).
let mask = (2 << 31 - Math.clz32((alphabet.length - 1) | 1)) - 1
// Though, the bitmask solution is not perfect since the bytes exceeding
// the alphabet size are refused. Therefore, to reliably generate the ID,
// the random bytes redundancy has to be satisfied.
// Note: every hardware random generator call is performance expensive,
// because the system call for entropy collection takes a lot of time.
// So, to avoid additional system calls, extra bytes are requested in advance.
// Next, a step determines how many random bytes to generate.
// The number of random bytes gets decided upon the ID size, mask,
// alphabet size, and magic number 1.6 (using 1.6 peaks at performance
// according to benchmarks).
let step = Math.ceil(1.6 * mask * size / alphabet.length)
return () => {
let id = ''
while (true) {
let bytes = getRandom(step)
// A compact alternative for `for (var i = 0; i < step; i++)`.
let i = step
while (i--) {
// Adding `|| ''` refuses a random byte that exceeds the alphabet size.
id += alphabet[bytes[i] & mask] || ''
// `id.length + 1 === size` is a more compact option.
if (id.length === +size) return id
}
}
}
}
let customAlphabet = (alphabet, size) => customRandom(alphabet, size, random)
let nanoid = (size = 21) => {
let bytes = random(size)
let id = ''
// A compact alternative for `for (var i = 0; i < step; i++)`.
while (size--) {
// We can’t use bytes bigger than the alphabet. 63 is 00111111 bitmask.
// This mask reduces random byte 0-255 to 0-63 values.
// There is no need in `|| ''` and `* 1.6` hacks in here,
// because bitmask trim bytes exact to alphabet size.
id += url[bytes[size] & 63]
// It is incorrect to use bytes exceeding the alphabet size.
// The following mask reduces the random byte in the 0-255 value
// range to the 0-63 value range. Therefore, adding hacks, such
// as empty string fallback or magic numbers, is unneccessary because
// the bitmask trims bytes down to the alphabet size.
id += urlAlphabet[bytes[size] & 63]
}
return id
}
export { nanoid, customAlphabet, customRandom, urlAlphabet, random }

@@ -1,42 +0,27 @@

// This alphabet uses a-z A-Z 0-9 _- symbols.
// Symbols are generated for smaller size.
// -_zyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBA
var url = '-_'
// Loop from 36 to 0 (from z to a and 9 to 0 in Base36).
var i = 36
while (i--) {
// 36 is radix. Number.prototype.toString(36) returns number
// in Base36 representation. Base36 is like hex, but it uses 0–9 and a-z.
url += i.toString(36)
import { urlAlphabet } from '../index.js'
let customAlphabet = (alphabet, size) => {
return () => {
let id = ''
// A compact alternative for `for (var i = 0; i < step; i++)`.
let i = size
while (i--) {
// `| 0` is more compact and faster than `Math.floor()`.
id += alphabet[Math.random() * alphabet.length | 0]
}
return id
}
}
// Loop from 36 to 10 (from Z to A in Base36).
i = 36
while (i-- - 10) {
url += i.toString(36).toUpperCase()
}
/**
* Generate URL-friendly unique ID. This method use non-secure predictable
* random generator with bigger collision probability.
*
* @param {number} [size=21] The number of symbols in ID.
*
* @return {string} Random string.
*
* @example
* const nanoid = require('nanoid/non-secure')
* model.id = nanoid() //=> "Uakgb_J5m9g-0JDMbcJqL"
*
* @name nonSecure
* @function
*/
module.exports = function (size) {
var id = ''
i = size || 21
// Compact alternative for `for (var i = 0; i < size; i++)`
let nanoid = (size = 21) => {
let id = ''
// A compact alternative for `for (var i = 0; i < step; i++)`.
let i = size
while (i--) {
// `| 0` is compact and faster alternative for `Math.floor()`
id += url[Math.random() * 64 | 0]
// `| 0` is more compact and faster than `Math.floor()`.
id += urlAlphabet[Math.random() * 64 | 0]
}
return id
}
export { nanoid, customAlphabet }
{
"name": "nanoid",
"version": "2.1.11",
"description": "A tiny (119 bytes), secure URL-friendly unique string ID generator",
"version": "3.0.0",
"description": "A tiny (108 bytes), secure URL-friendly unique string ID generator",
"keywords": [

@@ -15,20 +15,28 @@ "uuid",

"browser": {
"./index.js": "./index.browser.js",
"./format.js": "./format.browser.js",
"./random.js": "./random.browser.js",
"./async/index.js": "./async/index.browser.js",
"./async/format.js": "./async/format.browser.js",
"./async/random.js": "./async/random.browser.js"
"./index.js": "./index.browser.js"
},
"react-native": {
"./async/random.js": "./async/random.rn.js"
},
"sideEffects": false,
"eslintIgnore": [
"test/demo/build"
],
"sharec": {
"config": "@logux/sharec-config",
"version": "0.5.6"
"type": "module",
"main": "index.cjs",
"module": "index.js",
"react-native": "index.js",
"exports": {
"./package.json": "./package.json",
".": {
"require": "./index.cjs",
"import": "./index.js",
"browser": "./index.browser.js"
},
"./async/package.json": "./async/package.json",
"./async": {
"require": "./async/index.cjs",
"import": "./async/index.js",
"browser": "./async/index.browser.js"
},
"./non-secure/package.json": "./non-secure/package.json",
"./non-secure": {
"require": "./non-secure/index.cjs",
"import": "./non-secure/index.js"
}
}
}
}

@@ -8,7 +8,10 @@ # Nano ID

* **Small.** 119 bytes (minified and gzipped). No dependencies.
> “An amazing level of senseless perfectionism,
> which is simply impossible not to respect.”
* **Small.** 108 bytes (minified and gzipped). No dependencies.
[Size Limit] controls the size.
* **Safe.** It uses cryptographically strong random APIs.
Can be used in clusters.
* **Fast.** It’s 16% faster than UUID.
* **Fast.** It is 16% faster than UUID.
* **Compact.** It uses a larger alphabet than UUID (`A-Za-z0-9_-`).

@@ -18,10 +21,11 @@ So ID size was reduced from 36 to 21 symbols.

```js
const nanoid = require('nanoid')
import { nanoid } from 'nanoid'
model.id = nanoid() //=> "V1StGXR8_Z5jdHi6B-myT"
```
Supports [all browsers], Node.js and React Native.
Supports modern browsers, IE with Babel, Node.js and React Native.
Try to make us smaller in the [online tool].
[all browsers]: http://caniuse.com/#feat=getrandomvalues
[Size Limit]: https://github.com/ai/size-limit
[online tool]: https://gitpod.io/#https://github.com/ai/nanoid/
[Size Limit]: https://github.com/ai/size-limit

@@ -35,19 +39,20 @@ <a href="https://evilmartians.com/?utm_source=nanoid">

1. [Comparison with UUID](#comparison-with-uuid)
2. [Benchmark](#benchmark)
4. [Tools](#tools)
3. [Security](#security)
6. Usage
1. [JS](#js)
2. [React](#react)
3. [React Native](#react-native)
4. [Web Workers](#web-workers)
5. [PouchDB and CouchDB](#pouchdb-and-couchdb)
5. [Mongoose](#mongoose)
6. [Other Programming Languages](#other-programming-languages)
7. API
1. [Async](#async)
2. [Non-Secure](#non-secure)
3. [Custom Alphabet or Length](#custom-alphabet-or-length)
4. [Custom Random Bytes Generator](#custom-random-bytes-generator)
* [Comparison with UUID](#comparison-with-uuid)
* [Benchmark](#benchmark)
* [Tools](#tools)
* [Security](#security)
* [Usage](#usage)
* [JS](#js)
* [React](#react)
* [React Native](#react-native)
* [PouchDB and CouchDB](#pouchdb-and-couchdb)
* [Mongoose](#mongoose)
* [ES Modules](#es-modules)
* [Web Workers](#web-workers)
* [Other Programming Languages](#other-programming-languages)
* [API](#api)
* [Async](#async)
* [Non-Secure](#non-secure)
* [Custom Alphabet or Size](#custom-alphabet-or-size)
* [Custom Random Bytes Generator](#custom-random-bytes-generator)

@@ -68,4 +73,4 @@

are packed in just 21 symbols instead of 36.
2. Nano ID code is 4 times less than `uuid/v4` package:
119 bytes instead of 435.
2. Nano ID code is 3 times less than `uuid/v4` package:
108 bytes instead of 345.
3. Because of memory allocation tricks, Nano ID is 16% faster than UUID.

@@ -78,26 +83,29 @@

$ ./test/benchmark
nanoid 693,132 ops/sec
nanoid/generate 624,291 ops/sec
uid.sync 487,706 ops/sec
uuid/v4 471,299 ops/sec
secure-random-string 448,386 ops/sec
shortid 66,809 ops/sec
nanoid 655,798 ops/sec
customAlphabet 635,421 ops/sec
uid.sync 375,816 ops/sec
uuid v4 396,756 ops/sec
secure-random-string 366,434 ops/sec
shortid 59,343 ops/sec
Async:
nanoid/async 105,024 ops/sec
nanoid/async/generate 106,682 ops/sec
secure-random-string 94,217 ops/sec
uid 92,026 ops/sec
async nanoid 101,966 ops/sec
async customAlphabet 102,471 ops/sec
async secure-random-string 97,206 ops/sec
uid 91,291 ops/sec
Non-secure:
nanoid/non-secure 2,555,814 ops/sec
rndm 2,413,565 ops/sec
non-secure nanoid 2,754,423 ops/sec
rndm 2,437,262 ops/sec
```
Test configuration: Dell XPS 2-in-a 7390, Fedora 32, Node.js 13.11.
## Tools
* [ID size calculator] to choice smaller ID size depends on your case.
* [`nanoid-dictionary`] with popular alphabets to use with `nanoid/generate`.
* [`nanoid-cli`] to generate ID from CLI.
* [ID size calculator] shows collision probability when adjusting
the ID alphabet or size.
* [`nanoid-dictionary`] with popular alphabets to use with `customAlphabet`.
* [`nanoid-cli`] to generate IDs from CLI.
* [`nanoid-good`] to be sure that your ID doesn't contain any obscene words.

@@ -117,32 +125,22 @@

### Unpredictability
* **Unpredictability.** Instead of using the unsafe `Math.random()`, Nano ID
uses the `crypto` module in Node.js and the Web Crypto API in browsers.
These modules use unpredictable hardware random generator.
* **Uniformity.** `random % alphabet` is a popular mistake to make when coding
an ID generator. The distribution will not be even; there will be a lower
chance for some symbols to appear compared to others. So, it will reduce
the number of tries when brute-forcing. Nano ID uses a [better algorithm]
and is tested for uniformity.
Instead of using the unsafe `Math.random()`, Nano ID uses the `crypto` module
in Node.js and the Web Crypto API in browsers. These modules use unpredictable
hardware random generator.
<img src="img/distribution.png" alt="Nano ID uniformity"
width="340" height="135">
* **Vulnerabilities:** to report a security vulnerability, please use
the [Tidelift security contact](https://tidelift.com/security).
Tidelift will coordinate the fix and disclosure.
### Uniformity
`random % alphabet` is a popular mistake to make when coding an ID generator.
The spread will not be even; there will be a lower chance for some symbols
to appear compared to others—so it will reduce the number of tries
when brute-forcing.
Nano ID uses a [better algorithm] and is tested for uniformity.
<img src="img/distribution.png" alt="Nano ID uniformity"
width="340" height="135">
[Secure random values (in Node.js)]: https://gist.github.com/joepie91/7105003c3b26e65efcea63f3db82dfba
[better algorithm]: https://github.com/ai/nanoid/blob/master/format.js
[better algorithm]: https://github.com/ai/nanoid/blob/master/format.js
### Vulnerabilities
To report a security vulnerability, please use the
[Tidelift security contact](https://tidelift.com/security).
Tidelift will coordinate the fix and disclosure.
## Usage

@@ -156,8 +154,8 @@

```js
const nanoid = require('nanoid')
import { nanoid } from 'nanoid'
model.id = nanoid() //=> "Uakgb_J5m9g-0JDMbcJqLJ"
```
If you want to reduce ID length (and increase collisions probability),
you can pass the length as an argument.
If you want to reduce the ID size (and increase collisions probability),
you can pass the size as an argument.

@@ -168,7 +166,7 @@ ```js

Don’t forget to check the safety of your ID length
Don’t forget to check the safety of your ID size
in our [ID collision probability] calculator.
You can also use [custom alphabet](#custom-alphabet-or-length)
or [random generator](#custom-random-bytes-generator).
You can also use a [custom alphabet](#custom-alphabet-or-size)
or a [random generator](#custom-random-bytes-generator).

@@ -180,5 +178,7 @@ [ID collision probability]: https://zelark.github.io/nano-id-cc/

**Do not** use a nanoid for `key` prop. In React `key` should be consistence
between renders. This is bad code:
**Do not** call `nanoid` in the `key` prop. In React, `key` should be consistent
among renders.
This is the bad example:
```jsx

@@ -188,3 +188,3 @@ <Item key={nanoid()} /> /* DON’T DO IT */

This is good code. `id` will be generated only once:
This is the good example (`id` will be generated only once):

@@ -198,4 +198,4 @@ ```jsx

If you want to use Nano ID for `id`, you must to set some string prefix.
Nano ID could be started from number. HTML ID can’t be started from the number.
If you want to use Nano ID in the `key` prop, you must set some string prefix
(it is invalid for the HTML ID to start with a number).

@@ -209,16 +209,15 @@ ```jsx

React Native doesn’t have built-in random generator.
React Native does not have built-in random generator.
1. Check [`expo-random`] docs and install it.
2. Use `nanoid/async` instead of synchronous `nanoid`.
1. Check [`react-native-get-random-values`] docs and install it.
2. Import it before Nano ID.
```js
const nanoid = require('nanoid/async')
async function createUser () {
user.id = await nanoid()
}
import 'react-native-get-random-values'
import { nanoid } from 'nanoid'
```
[`react-native-get-random-values`]: https://github.com/LinusU/react-native-get-random-values
### PouchDB and CouchDB

@@ -252,23 +251,43 @@

### Web Workers
### ES Modules
Web Workers don’t have access to a secure random generator.
Nano ID provides ES modules. You do not need to do anything to use Nano ID
as ESM in webpack, Parcel, or Node.js.
Security is important in IDs, when IDs should be unpredictable. For instance,
in “access by URL” link generation.
```js
import { nanoid } from 'nanoid'
```
If you don’t need unpredictable IDs, but you need Web Workers support,
you can use non‑secure ID generator. Note, that they have bigger collision
probability.
For quick hacks, you can load Nano ID from CDN. Special minified
`nanoid.js` module is available on jsDelivr.
Though, it is not recommended to be used in production
because of the lower performance.
```js
const nanoid = require('nanoid/non-secure')
import { nanoid } from 'https://cdn.jsdelivr.net/npm/nanoid/nanoid.js'
```
### Web Workers
Web Workers do not have access to a secure random generator.
Security is important in IDs, when IDs should be unpredictable.
For instance, in "access by URL" link generation.
If you do not need unpredictable IDs, but you need to use Web Workers,
you can use the non‑secure ID generator.
```js
import { nanoid } from 'nanoid/non-secure'
nanoid() //=> "Uakgb_J5m9g-0JDMbcJqLJ"
```
Note: non-secure IDs are more prone to collision attacks.
### Other Programming Languages
Nano ID was ported to many languages. You can use these ports to have the same
ID generators on client and server side.
Nano ID was ported to many languages. You can use these ports to have
the same ID generator on the client and server side.

@@ -285,3 +304,4 @@ * [C#](https://github.com/codeyu/nanoid-net)

* [PHP](https://github.com/hidehalo/nanoid-php)
* [Python](https://github.com/puyuan/py-nanoid) with [dictionaries](https://pypi.org/project/nanoid-dictionary)
* [Python](https://github.com/puyuan/py-nanoid)
with [dictionaries](https://pypi.org/project/nanoid-dictionary)
* [Ruby](https://github.com/radeno/nanoid.rb)

@@ -300,10 +320,11 @@ * [Rust](https://github.com/nikolay-govorov/nanoid)

To generate hardware random bytes, CPU will collect electromagnetic noise.
During the collection, CPU doesn’t work.
To generate hardware random bytes, CPU collects electromagnetic noise.
In the synchronous API during the noise collection,
the CPU does not do anything useful.
If we will use asynchronous API for random generator,
another code could be executed during the entropy collection.
Using the asynchronous API of Nano ID, another code can run during
the entropy collection.
```js
const nanoid = require('nanoid/async')
import { nanoid } from 'nanoid/async'

@@ -315,4 +336,5 @@ async function createUser () {

Unfortunately, you will not have any benefits in a browser, since Web Crypto API
doesn’t have asynchronous API.
Unfortunately, you will lose Web Crypto API advantages in a browser
if you the asynchronous API. So, currently, in the browser, you are limited
with either security or asynchronous behavior.

@@ -322,37 +344,39 @@

By default, Nano ID uses hardware random generator for security
and low collision probability. If you don’t need it, you can use
very fast non-secure generator.
By default, Nano ID uses hardware random bytes generation for security
and low collision probability. If you are not so concerned with security
and more with performance, you can use the faster non-secure generator.
```js
const nonSecure = require('nanoid/non-secure')
const id = nonSecure() //=> "Uakgb_J5m9g-0JDMbcJqLJ"
import { nanoid } from 'nanoid/non-secure'
const id = nanoid() //=> "Uakgb_J5m9g-0JDMbcJqLJ"
```
Note that it is predictable and have bigger collision probability.
Note: your IDs will be more predictable and prone to collision attacks.
### Custom Alphabet or Length
### Custom Alphabet or Size
If you want to change the ID's alphabet or length
you can use the low-level `generate` module.
`customAlphabet` allows you to create `nanoid` with your own alphabet
and ID size.
```js
const generate = require('nanoid/generate')
model.id = generate('1234567890abcdef', 10) //=> "4f90d13a42"
import { customAlphabet } from 'nanoid'
const nanoid = customAlphabet('1234567890abcdef', 10)
model.id = nanoid() //=> "4f90d13a42"
```
Check the safety of your custom alphabet and ID length
in our [ID collision probability] calculator.
You can find popular alphabets in [`nanoid-dictionary`].
Check the safety of your custom alphabet and ID size in our
[ID collision probability] calculator. For more alphabets, check out the options
in [`nanoid-dictionary`].
Alphabet must contain 256 symbols or less.
Otherwise, the generator will not be secure.
Otherwise, the security of the internal generator algorithm is not guaranteed.
Asynchronous and non-secure API is also available:
Customizable asynchronous and non-secure APIs are also available:
```js
const generate = require('nanoid/async/generate')
import { customAlphabet } from 'nanoid/async'
const nanoid = customAlphabet('1234567890abcdef', 10)
async function createUser () {
user.id = await generate('1234567890abcdef', 10)
user.id = await nanoid()
}

@@ -362,5 +386,5 @@ ```

```js
const generate = require('nanoid/non-secure/generate')
user.id = generate('1234567890abcdef', 10)
import { customAlphabet } from 'nanoid/non-secure'
const nanoid = customAlphabet('1234567890abcdef', 10)
user.id = nanoid()
```

@@ -374,17 +398,16 @@

You can replace the default safe random generator using the `format` module.
For instance, to use a seed-based generator.
`customRandom` allows you to create a `nanoid` and replace alphabet
and the default random bytes generator.
In this example, a seed-based generator is used:
```js
const format = require('nanoid/format')
import { customRandom } from 'nanoid'
function random (size) {
const result = []
for (let i = 0; i < size; i++) {
result.push(randomByte())
}
return result
}
const rng = seedrandom(seed)
const nanoid = customRandom('abcdef', 10, size => {
return (new Uint8Array(size)).map(() => 256 * rng())
})
format(random, "abcdef", 10) //=> "fbaefaadeb"
nanoid() //=> "fbaefaadeb"
```

@@ -395,23 +418,10 @@

If you want to use the same URL-friendly symbols with `format`,
you can get the default alphabet from the `url` file.
If you want to use the same URL-friendly symbols with `customRandom`,
you can get the default alphabet using the `urlAlphabet`.
```js
const url = require('nanoid/url')
format(random, url, 10) //=> "93ce_Ltuub"
const { customRandom, urlAlphabet } = require('nanoid')
const nanoid = customRandom(urlAlphabet, 10, random)
```
Asynchronous API is also available:
```js
const format = require('nanoid/async/format')
const url = require('nanoid/url')
function random (size) {
return new Promise(…)
}
async function createUser () {
user.id = await format(random, url, 10)
}
```
Asynchronous and non-secure APIs are not available for `customRandom`.
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc