source: imaps-frontend/node_modules/nanoid/README.md@ 0c6b92a

main
Last change on this file since 0c6b92a was 0c6b92a, checked in by stefan toskovski <stefantoska84@…>, 5 weeks ago

Pred finalna verzija

  • Property mode set to 100644
File size: 15.6 KB
RevLine 
[d565449]1# Nano ID
2
3<img src="https://ai.github.io/nanoid/logo.svg" align="right"
4 alt="Nano ID logo by Anton Lovchikov" width="180" height="94">
5
6**English** | [Русский](./README.ru.md) | [简体中文](./README.zh-CN.md) | [Bahasa Indonesia](./README.id-ID.md)
7
8A tiny, secure, URL-friendly, unique string ID generator for JavaScript.
9
10> “An amazing level of senseless perfectionism,
11> which is simply impossible not to respect.”
12
13* **Small.** 130 bytes (minified and gzipped). No dependencies.
14 [Size Limit] controls the size.
15* **Fast.** It is 2 times faster than UUID.
16* **Safe.** It uses hardware random generator. Can be used in clusters.
17* **Short IDs.** It uses a larger alphabet than UUID (`A-Za-z0-9_-`).
18 So ID size was reduced from 36 to 21 symbols.
19* **Portable.** Nano ID was ported
20 to [20 programming languages](#other-programming-languages).
21
22```js
23import { nanoid } from 'nanoid'
24model.id = nanoid() //=> "V1StGXR8_Z5jdHi6B-myT"
25```
26
27Supports modern browsers, IE [with Babel], Node.js and React Native.
28
29[online tool]: https://gitpod.io/#https://github.com/ai/nanoid/
30[with Babel]: https://developer.epages.com/blog/coding/how-to-transpile-node-modules-with-babel-and-webpack-in-a-monorepo/
31[Size Limit]: https://github.com/ai/size-limit
32
33<a href="https://evilmartians.com/?utm_source=nanoid">
34 <img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg"
35 alt="Sponsored by Evil Martians" width="236" height="54">
36</a>
37
[0c6b92a]38## Table of Contents
39
40* [Comparison with UUID](#comparison-with-uuid)
41* [Benchmark](#benchmark)
42* [Security](#security)
43* [API](#api)
44 * [Blocking](#blocking)
45 * [Async](#async)
46 * [Non-Secure](#non-secure)
47 * [Custom Alphabet or Size](#custom-alphabet-or-size)
48 * [Custom Random Bytes Generator](#custom-random-bytes-generator)
49* [Usage](#usage)
50 * [IE](#ie)
51 * [React](#react)
52 * [React Native](#react-native)
53 * [Rollup](#rollup)
54 * [PouchDB and CouchDB](#pouchdb-and-couchdb)
55 * [Mongoose](#mongoose)
56 * [Web Workers](#web-workers)
57 * [CLI](#cli)
58 * [Other Programming Languages](#other-programming-languages)
59* [Tools](#tools)
60
61
62## Comparison with UUID
63
64Nano ID is quite comparable to UUID v4 (random-based).
65It has a similar number of random bits in the ID
66(126 in Nano ID and 122 in UUID), so it has a similar collision probability:
67
68> For there to be a one in a billion chance of duplication,
69> 103 trillion version 4 IDs must be generated.
70
71There are three main differences between Nano ID and UUID v4:
72
731. Nano ID uses a bigger alphabet, so a similar number of random bits
74 are packed in just 21 symbols instead of 36.
752. Nano ID code is **4 times less** than `uuid/v4` package:
76 130 bytes instead of 483.
773. Because of memory allocation tricks, Nano ID is **2 times** faster than UUID.
78
79
80## Benchmark
81
82```rust
83$ node ./test/benchmark.js
84crypto.randomUUID 25,603,857 ops/sec
85@napi-rs/uuid 9,973,819 ops/sec
86uid/secure 8,234,798 ops/sec
87@lukeed/uuid 7,464,706 ops/sec
88nanoid 5,616,592 ops/sec
89customAlphabet 3,115,207 ops/sec
90uuid v4 1,535,753 ops/sec
91secure-random-string 388,226 ops/sec
92uid-safe.sync 363,489 ops/sec
93cuid 187,343 ops/sec
94shortid 45,758 ops/sec
95
96Async:
97nanoid/async 96,094 ops/sec
98async customAlphabet 97,184 ops/sec
99async secure-random-string 92,794 ops/sec
100uid-safe 90,684 ops/sec
101
102Non-secure:
103uid 67,376,692 ops/sec
104nanoid/non-secure 2,849,639 ops/sec
105rndm 2,674,806 ops/sec
106```
107
108Test configuration: ThinkPad X1 Carbon Gen 9, Fedora 34, Node.js 16.10.
109
110
111## Security
112
113*See a good article about random generators theory:
114[Secure random values (in Node.js)]*
115
116* **Unpredictability.** Instead of using the unsafe `Math.random()`, Nano ID
117 uses the `crypto` module in Node.js and the Web Crypto API in browsers.
118 These modules use unpredictable hardware random generator.
119* **Uniformity.** `random % alphabet` is a popular mistake to make when coding
120 an ID generator. The distribution will not be even; there will be a lower
121 chance for some symbols to appear compared to others. So, it will reduce
122 the number of tries when brute-forcing. Nano ID uses a [better algorithm]
123 and is tested for uniformity.
124
125 <img src="img/distribution.png" alt="Nano ID uniformity"
126 width="340" height="135">
127
128* **Well-documented:** all Nano ID hacks are documented. See comments
129 in [the source].
130* **Vulnerabilities:** to report a security vulnerability, please use
131 the [Tidelift security contact](https://tidelift.com/security).
132 Tidelift will coordinate the fix and disclosure.
133
134[Secure random values (in Node.js)]: https://gist.github.com/joepie91/7105003c3b26e65efcea63f3db82dfba
135[better algorithm]: https://github.com/ai/nanoid/blob/main/index.js
136[the source]: https://github.com/ai/nanoid/blob/main/index.js
137
138
139## Install
140
141```bash
142npm install --save nanoid
143```
144
145For quick hacks, you can load Nano ID from CDN. Though, it is not recommended
146to be used in production because of the lower loading performance.
147
148```js
149import { nanoid } from 'https://cdn.jsdelivr.net/npm/nanoid/nanoid.js'
150```
151
152Nano ID provides ES modules. You do not need to do anything to use Nano ID
153as ESM in webpack, Rollup, Parcel, or Node.js.
154
155```js
156import { nanoid } from 'nanoid'
157```
158
159In Node.js you can use CommonJS import:
160
161```js
162const { nanoid } = require('nanoid')
163```
164
165
166## API
167
168Nano ID has 3 APIs: normal (blocking), asynchronous, and non-secure.
169
170By default, Nano ID uses URL-friendly symbols (`A-Za-z0-9_-`) and returns an ID
171with 21 characters (to have a collision probability similar to UUID v4).
172
173
174### Blocking
175
176The safe and easiest way to use Nano ID.
177
178In rare cases could block CPU from other work while noise collection
179for hardware random generator.
180
181```js
182import { nanoid } from 'nanoid'
183model.id = nanoid() //=> "V1StGXR8_Z5jdHi6B-myT"
184```
185
186If you want to reduce the ID size (and increase collisions probability),
187you can pass the size as an argument.
188
189```js
190nanoid(10) //=> "IRFa-VaY2b"
191```
192
193Don’t forget to check the safety of your ID size
194in our [ID collision probability] calculator.
195
196You can also use a [custom alphabet](#custom-alphabet-or-size)
197or a [random generator](#custom-random-bytes-generator).
198
199[ID collision probability]: https://zelark.github.io/nano-id-cc/
200
201
202### Async
203
204To generate hardware random bytes, CPU collects electromagnetic noise.
205For most cases, entropy will be already collected.
206
207In the synchronous API during the noise collection, the CPU is busy and
208cannot do anything useful (for instance, process another HTTP request).
209
210Using the asynchronous API of Nano ID, another code can run during
211the entropy collection.
212
213```js
214import { nanoid } from 'nanoid/async'
215
216async function createUser () {
217 user.id = await nanoid()
218}
219```
220
221Read more about entropy collection in [`crypto.randomBytes`] docs.
222
223Unfortunately, you will lose Web Crypto API advantages in a browser
224if you use the asynchronous API. So, currently, in the browser, you are limited
225with either security (`nanoid`), asynchronous behavior (`nanoid/async`),
226or non-secure behavior (`nanoid/non-secure`) that will be explained
227in the next part of the documentation.
228
229[`crypto.randomBytes`]: https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback
230
231
232### Non-Secure
233
234By default, Nano ID uses hardware random bytes generation for security
235and low collision probability. If you are not so concerned with security,
236you can use the faster non-secure generator.
237
238```js
239import { nanoid } from 'nanoid/non-secure'
240const id = nanoid() //=> "Uakgb_J5m9g-0JDMbcJqLJ"
241```
242
243
244### Custom Alphabet or Size
245
246`customAlphabet` allows you to create `nanoid` with your own alphabet
247and ID size.
248
249```js
250import { customAlphabet } from 'nanoid'
251const nanoid = customAlphabet('1234567890abcdef', 10)
252model.id = nanoid() //=> "4f90d13a42"
253```
254
255```js
256import { customAlphabet } from 'nanoid/async'
257const nanoid = customAlphabet('1234567890abcdef', 10)
258async function createUser () {
259 user.id = await nanoid()
260}
261```
262
263```js
264import { customAlphabet } from 'nanoid/non-secure'
265const nanoid = customAlphabet('1234567890abcdef', 10)
266user.id = nanoid()
267```
268
269Check the safety of your custom alphabet and ID size in our
270[ID collision probability] calculator. For more alphabets, check out the options
271in [`nanoid-dictionary`].
272
273Alphabet must contain 256 symbols or less.
274Otherwise, the security of the internal generator algorithm is not guaranteed.
275
276In addition to setting a default size, you can change the ID size when calling
277the function:
278
279```js
280import { customAlphabet } from 'nanoid'
281const nanoid = customAlphabet('1234567890abcdef', 10)
282model.id = nanoid(5) //=> "f01a2"
283```
284
285[ID collision probability]: https://alex7kom.github.io/nano-nanoid-cc/
286[`nanoid-dictionary`]: https://github.com/CyberAP/nanoid-dictionary
287
288
289### Custom Random Bytes Generator
290
291`customRandom` allows you to create a `nanoid` and replace alphabet
292and the default random bytes generator.
293
294In this example, a seed-based generator is used:
295
296```js
297import { customRandom } from 'nanoid'
298
299const rng = seedrandom(seed)
300const nanoid = customRandom('abcdef', 10, size => {
301 return (new Uint8Array(size)).map(() => 256 * rng())
302})
303
304nanoid() //=> "fbaefaadeb"
305```
306
307`random` callback must accept the array size and return an array
308with random numbers.
309
310If you want to use the same URL-friendly symbols with `customRandom`,
311you can get the default alphabet using the `urlAlphabet`.
312
313```js
314const { customRandom, urlAlphabet } = require('nanoid')
315const nanoid = customRandom(urlAlphabet, 10, random)
316```
317
318Asynchronous and non-secure APIs are not available for `customRandom`.
319
320Note, that between Nano ID versions we may change random generator
321call sequence. If you are using seed-based generators, we do not guarantee
322the same result.
323
324
325## Usage
326
327### IE
328
329If you support IE, you need to [transpile `node_modules`] by Babel
330and add `crypto` alias. Moreover, `UInt8Array` in IE actually
331is not an array and to cope with it, you have to convert it to an array
332manually:
333
334```js
335// polyfills.js
336if (!window.crypto && window.msCrypto) {
337 window.crypto = window.msCrypto
338
339 const getRandomValuesDef = window.crypto.getRandomValues
340
341 window.crypto.getRandomValues = function (array) {
342 const values = getRandomValuesDef.call(window.crypto, array)
343 const result = []
344
345 for (let i = 0; i < array.length; i++) {
346 result[i] = values[i];
347 }
348
349 return result
350 };
351}
352```
353
354```js
355import './polyfills.js'
356import { nanoid } from 'nanoid'
357```
358
359[transpile `node_modules`]: https://developer.epages.com/blog/coding/how-to-transpile-node-modules-with-babel-and-webpack-in-a-monorepo/
360
361
362### React
363
364There’s no correct way to use Nano ID for React `key` prop
365since it should be consistent among renders.
366
367```jsx
368function Todos({todos}) {
369 return (
370 <ul>
371 {todos.map(todo => (
372 <li key={nanoid()}> /* DON’T DO IT */
373 {todo.text}
374 </li>
375 ))}
376 </ul>
377 )
378}
379```
380
381You should rather try to reach for stable ID inside your list item.
382
383```jsx
384const todoItems = todos.map((todo) =>
385 <li key={todo.id}>
386 {todo.text}
387 </li>
388)
389```
390
391In case you don’t have stable IDs you'd rather use index as `key`
392instead of `nanoid()`:
393
394```jsx
395const todoItems = todos.map((text, index) =>
396 <li key={index}> /* Still not recommended but preferred over nanoid().
397 Only do this if items have no stable IDs. */
398 {text}
399 </li>
400)
401```
402
403
404### React Native
405
406React Native does not have built-in random generator. The following polyfill
407works for plain React Native and Expo starting with `39.x`.
408
4091. Check [`react-native-get-random-values`] docs and install it.
4102. Import it before Nano ID.
411
412```js
413import 'react-native-get-random-values'
414import { nanoid } from 'nanoid'
415```
416
417[`react-native-get-random-values`]: https://github.com/LinusU/react-native-get-random-values
418
419
420### Rollup
421
422For Rollup you will need [`@rollup/plugin-node-resolve`] to bundle browser version
423of this library.:
424
425```js
426 plugins: [
427 nodeResolve({
428 browser: true
429 })
430 ]
431```
432
433[`@rollup/plugin-node-resolve`]: https://github.com/rollup/plugins/tree/master/packages/node-resolve
434
435
436### PouchDB and CouchDB
437
438In PouchDB and CouchDB, IDs can’t start with an underscore `_`.
439A prefix is required to prevent this issue, as Nano ID might use a `_`
440at the start of the ID by default.
441
442Override the default ID with the following option:
443
444```js
445db.put({
446 _id: 'id' + nanoid(),
447
448})
449```
450
451
452### Mongoose
453
454```js
455const mySchema = new Schema({
456 _id: {
457 type: String,
458 default: () => nanoid()
459 }
460})
461```
462
463
464### Web Workers
465
466Web Workers do not have access to a secure random generator.
467
468Security is important in IDs when IDs should be unpredictable.
469For instance, in "access by URL" link generation.
470If you do not need unpredictable IDs, but you need to use Web Workers,
471you can use the non‑secure ID generator.
472
473```js
474import { nanoid } from 'nanoid/non-secure'
475nanoid() //=> "Uakgb_J5m9g-0JDMbcJqLJ"
476```
477
478Note: non-secure IDs are more prone to collision attacks.
479
480
481### CLI
482
483You can get unique ID in terminal by calling `npx nanoid`. You need only
484Node.js in the system. You do not need Nano ID to be installed anywhere.
485
486```sh
487$ npx nanoid
488npx: installed 1 in 0.63s
489LZfXLFzPPR4NNrgjlWDxn
490```
491
492Size of generated ID can be specified with `--size` (or `-s`) option:
493
494```sh
495$ npx nanoid --size 10
496L3til0JS4z
497```
498
499Custom alphabet can be specified with `--alphabet` (or `-a`) option
500(note that in this case `--size` is required):
501
502```sh
503$ npx nanoid --alphabet abc --size 15
504bccbcabaabaccab
505```
506
507### Other Programming Languages
508
509Nano ID was ported to many languages. You can use these ports to have
510the same ID generator on the client and server side.
511
512* [C#](https://github.com/codeyu/nanoid-net)
513* [C++](https://github.com/mcmikecreations/nanoid_cpp)
514* [Clojure and ClojureScript](https://github.com/zelark/nano-id)
515* [ColdFusion/CFML](https://github.com/JamoCA/cfml-nanoid)
516* [Crystal](https://github.com/mamantoha/nanoid.cr)
517* [Dart & Flutter](https://github.com/pd4d10/nanoid-dart)
518* [Deno](https://github.com/ianfabs/nanoid)
519* [Go](https://github.com/matoous/go-nanoid)
520* [Elixir](https://github.com/railsmechanic/nanoid)
521* [Haskell](https://github.com/MichelBoucey/NanoID)
522* [Janet](https://sr.ht/~statianzo/janet-nanoid/)
523* [Java](https://github.com/aventrix/jnanoid)
524* [Nim](https://github.com/icyphox/nanoid.nim)
525* [OCaml](https://github.com/routineco/ocaml-nanoid)
526* [Perl](https://github.com/tkzwtks/Nanoid-perl)
527* [PHP](https://github.com/hidehalo/nanoid-php)
528* [Python](https://github.com/puyuan/py-nanoid)
529 with [dictionaries](https://pypi.org/project/nanoid-dictionary)
530* [Postgres Extension](https://github.com/spa5k/uids-postgres)
531* [R](https://github.com/hrbrmstr/nanoid) (with dictionaries)
532* [Ruby](https://github.com/radeno/nanoid.rb)
533* [Rust](https://github.com/nikolay-govorov/nanoid)
534* [Swift](https://github.com/antiflasher/NanoID)
535* [Unison](https://share.unison-lang.org/latest/namespaces/hojberg/nanoid)
536* [V](https://github.com/invipal/nanoid)
537* [Zig](https://github.com/SasLuca/zig-nanoid)
538
539For other environments, [CLI] is available to generate IDs from a command line.
540
541[CLI]: #cli
542
543
544## Tools
545
546* [ID size calculator] shows collision probability when adjusting
547 the ID alphabet or size.
548* [`nanoid-dictionary`] with popular alphabets to use with [`customAlphabet`].
549* [`nanoid-good`] to be sure that your ID doesn’t contain any obscene words.
550
551[`nanoid-dictionary`]: https://github.com/CyberAP/nanoid-dictionary
552[ID size calculator]: https://zelark.github.io/nano-id-cc/
553[`customAlphabet`]: #custom-alphabet-or-size
554[`nanoid-good`]: https://github.com/y-gagar1n/nanoid-good
Note: See TracBrowser for help on using the repository browser.