nanoid 3.1.27 → 3.1.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.ru.md DELETED
@@ -1,513 +0,0 @@
1
- # Nano ID
2
-
3
- <img src="https://ai.github.io/nanoid/logo.svg" align="right"
4
- alt="Логотип Nano ID от Антона Ловчикова" width="180" height="94">
5
-
6
- [English](./README.md) | **Русский** | [简体中文](./README.zh-CN.md)
7
-
8
- Генератор уникальных ID для JavaScript — лёгкий, безопасный,
9
- ID можно применять в URL.
10
-
11
- > «Поразительный уровень бессмысленного перфекционизма,
12
- > который просто невозможно не уважать»
13
-
14
- - **Лёгкий.** 108 байт (после минификации и gzip). Без зависимостей.
15
- [Size Limit] следит за размером.
16
- - **Быстрый.** В 2 раза быстрее UUID.
17
- - **Безопасный.** Использует аппаратный генератор случайных чисел.
18
- Можно использовать в кластерах машин.
19
- - **Короткие ID.** Используется больший алфавит, чем у UUID (`A-Za-z0-9_-`).
20
- Поэтому длина ID уменьшена с 36 до 21 символа.
21
- - **Работает везде.** Nano ID уже портировали
22
- на [19 языков программирования](#другие-языки-программирования).
23
-
24
- ```js
25
- import { nanoid } from 'nanoid'
26
- model.id = nanoid() //=> "V1StGXR8_Z5jdHi6B-myT"
27
- ```
28
-
29
- Поддерживает современные браузеры, IE ([с Babel]), Node.js и React Native.
30
-
31
- [online tool]: https://gitpod.io/#https://github.com/ai/nanoid/
32
- [с babel]: https://developer.epages.com/blog/coding/how-to-transpile-node-modules-with-babel-and-webpack-in-a-monorepo/
33
- [size limit]: https://github.com/ai/size-limit
34
-
35
- <a href="https://evilmartians.com/?utm_source=nanoid">
36
- <img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg"
37
- alt="При поддержке Злых марсиан" width="236" height="54">
38
- </a>
39
-
40
-
41
- ## Оглавление
42
-
43
- - [Сравнение с UUID](#сравнение-с-uuid)
44
- - [Сравнение производительности](#сравнение-производительности)
45
- - [Безопасность](#безопасность)
46
- - [Подключение](#подключение)
47
- - [API](#api)
48
- - [Блокирующий](#блокирующий)
49
- - [Асинхронный](#асинхронный)
50
- - [Небезопасный](#небезопасный)
51
- - [Смена алфавита или длины](#смена-алфавита-или-длины)
52
- - [Смена генератора случайных чисел](#смена-генератора-случайных-чисел)
53
- - [Руководство](#руководство)
54
- - [IE](#ie)
55
- - [React](#react)
56
- - [HTML ID](#html-id)
57
- - [React Native](#react-native)
58
- - [Rollup](#rollup)
59
- - [PouchDB и CouchDB](#pouchdb-и-couchdb)
60
- - [Mongoose](#mongoose)
61
- - [Веб-воркеры](#веб-воркеры)
62
- - [Терминал](#терминал)
63
- - [Другие языки программирования](#другие-языки-программирования)
64
- - [Инструменты](#инструменты)
65
-
66
-
67
- ## Сравнение с UUID
68
-
69
- Nano ID похож на UUID v4 (случайный).
70
- У них сравнимое число битов случайности в ID (126 у Nano ID против 122 у UUID),
71
- поэтому они обладают похожей вероятностью возникновения коллизий
72
- (повторной генерации ранее выданных ID):
73
-
74
- > Чтобы вероятность повтора приблизилась к 1 на миллиард,
75
- > нужно сгенерировать 103 триллиона ID.
76
-
77
- Но между ними есть 3 важных отличия:
78
-
79
- 1. Nano ID использует более широкий алфавит, и сравнимое количество
80
- битов случайности будут упакованы в более короткую строку
81
- (21 символ, против 36 у UUID).
82
- 2. Код Nano ID **в 4.5 раз меньше**, чем у `uuid/v4` — 108 байт против 483.
83
- 3. Благодаря оптимизациям с выделением памяти,
84
- Nano ID **в 2 раза быстрее** UUID.
85
-
86
-
87
- ## Сравнение производительности
88
-
89
- ```rust
90
- $ node ./test/benchmark.js
91
- nanoid 4,975,393 ops/sec
92
- customAlphabet 2,717,877 ops/sec
93
- uuid v4 1,778,339 ops/sec
94
- uid.sync 391,311 ops/sec
95
- secure-random-string 372,537 ops/sec
96
- cuid 201,645 ops/sec
97
- shortid 50,462 ops/sec
98
-
99
- Async:
100
- async nanoid 95,500 ops/sec
101
- async customAlphabet 93,800 ops/sec
102
- async secure-random-string 90,316 ops/sec
103
- uid 85,583 ops/sec
104
-
105
- Non-secure:
106
- non-secure nanoid 2,641,654 ops/sec
107
- rndm 2,447,086 ops/sec
108
- ```
109
-
110
- Среда сравнения: ThinkPad X1 Carbon Gen 9, Fedora 34, Node.js 16.8.
111
-
112
-
113
- ## Безопасность
114
-
115
- _См. также хорошую статью о теориях генераторов случайных чисел:
116
- [Secure random values (in Node.js)]_
117
-
118
- - **Непредсказуемость.** Вместо предсказуемого `Math.random()`, Nano ID
119
- использует модуль `crypto` в Node.js и Web Crypto API в браузере.
120
- Эти модули дают доступ к аппаратному генератору случайных чисел.
121
- - **Равномерность.** Например, существует популярная ошибка `random % alphabet`,
122
- которую часто допускают при разработке генератора ID.
123
- Распределение вероятности для каждого символа может не быть одинаковым.
124
- Из-за неравномерности использования пространства алфавита, на перебор ID
125
- потребуется меньше времени, чем ожидается.
126
- Nano ID использует [более совершенный алгоритм],
127
- а равномерность распределения символов покрыта тестами.
128
-
129
- <img src="img/distribution.png" alt="Распределение Nano ID"
130
- width="340" height="135">
131
-
132
- - **Документация:** все хитрости Nano ID хорошо документированы — смотрите
133
- комментарии [в исходниках].
134
- - **Уязвимости:** если вы нашли уязвимость в Nano ID, свяжитесь с
135
- [командой безопасности Tidelift](https://tidelift.com/security).
136
- Они проконтролируют исправление и проинформируют пользователей.
137
-
138
- [secure random values (in node.js)]: https://gist.github.com/joepie91/7105003c3b26e65efcea63f3db82dfba
139
- [более совершенный алгоритм]: https://github.com/ai/nanoid/blob/main/index.js
140
- [в исходниках]: https://github.com/ai/nanoid/blob/main/index.js
141
-
142
-
143
- ## Подключение
144
-
145
- ```bash
146
- npm install --save nanoid
147
- ```
148
-
149
- Для быстрого прототипирования вы можете подключить Nano ID с CDN без установки.
150
- Не используйте этот способ на реальном сайте, так как он сильно бьёт
151
- по скорости загрузки сайта.
152
-
153
- ```js
154
- import { nanoid } from 'https://cdn.jsdelivr.net/npm/nanoid/nanoid.js'
155
- ```
156
-
157
- Nano ID поддерживает ES-модули. Вам не надо ничего делать, чтобы ES-импорты
158
- работали в webpack, Rollup, Parcel, или Node.js.
159
-
160
- ```js
161
- import { nanoid } from 'nanoid'
162
- ```
163
-
164
- Для Node.js также поддерживается CommonJS-импорт:
165
-
166
- ```js
167
- const { nanoid } = require('nanoid')
168
- ```
169
-
170
-
171
- ## API
172
-
173
- Nano ID разделён на три модуля:
174
- стандартный (блокирующий), асинхронный и небезопасный.
175
-
176
- По умолчанию используются символы, безопасные для URL (`A-Za-z0-9_-`).
177
- Длина ID по умолчанию — 21 символ
178
- (чтобы вероятность коллизий была соизмеримой с UUID v4).
179
-
180
-
181
- ### Блокирующий
182
-
183
- Безопасный и простой в использовании способ использования Nano ID.
184
-
185
- Из-за особенностей работы генератора случайных чисел при использовании этого
186
- способа ЦПУ может иногда простаивать без работы.
187
-
188
- ```js
189
- import { nanoid } from 'nanoid'
190
- model.id = nanoid() //=> "V1StGXR8_Z5jdHi6B-myT"
191
- ```
192
-
193
- Функция также принимает необязательный аргумент, задающий длину ID:
194
-
195
- ```js
196
- nanoid(10) //=> "IRFa-VaY2b"
197
- ```
198
-
199
- При изменении размера, всегда проверяйте риски
200
- в нашем [калькуляторе коллизий](https://zelark.github.io/nano-id-cc/).
201
-
202
-
203
- ### Асинхронный
204
-
205
- Для аппаратной генерации случайных чисел процессор накапливает
206
- электромагнитные шумы. Обычно они накоплены заранее, и получение
207
- случайных чисел происходит быстро. Но могут быть ситуации, когда
208
- системе требуется время на накопление энтропии.
209
-
210
- При использовании синхронного API процесс заблокируется
211
- во время накопления энтропии. Например, веб-сервер не сможет
212
- обрабатывать запрос следующего посетителя, пока не сгенерирует
213
- ID для предыдущего.
214
-
215
- Но если использовать асинхронный API у Nano ID, то процесс будет работать
216
- более эффективно: во время накопления шума сможет выполняться другая задача.
217
-
218
- ```js
219
- import { nanoid } from 'nanoid/async'
220
-
221
- async function createUser() {
222
- user.id = await nanoid()
223
- }
224
- ```
225
-
226
- Про ожидание накопления энтропии можно почитать в описании метода
227
- `crypto.randomBytes` в [документации Node.js].
228
-
229
- К сожалению, эта оптимизация имеет смысл только для Node.js. Web Crypto API
230
- в браузерах не имеет асинхронной версии.
231
-
232
- [документации node.js]: https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback
233
-
234
-
235
- ### Небезопасный
236
-
237
- По умолчанию, Nano ID использует аппаратный генератор случайных чисел для
238
- получения непредсказуемых ID и минимизации риска возникновения коллизий
239
- (повторной генерации ранее выданных ID).
240
- Но если вам не требуется устойчивость к подбору ID,
241
- то вы можете ускорить генерацию ID, перейдя на небезопасный генератор.
242
-
243
- ```js
244
- import { nanoid } from 'nanoid/non-secure'
245
- const id = nanoid() //=> "Uakgb_J5m9g-0JDMbcJqLJ"
246
- ```
247
-
248
- Но учтите, что предсказуемость ID может быть использована для атаки на систему.
249
-
250
-
251
- ### Смена алфавита или длины
252
-
253
- Функция `customAlphabet` позволяет создать свою функцию `nanoid`
254
- с нужным вам алфавитом и длиной ID.
255
-
256
- ```js
257
- import { customAlphabet } from 'nanoid'
258
- const nanoid = customAlphabet('1234567890abcdef', 10)
259
- user.id = nanoid() //=> "4f90d13a42"
260
- ```
261
-
262
- ```js
263
- import { customAlphabet } from 'nanoid/async'
264
- const nanoid = customAlphabet('1234567890abcdef', 10)
265
- async function createUser() {
266
- user.id = await nanoid()
267
- }
268
- ```
269
-
270
- ```js
271
- import { customAlphabet } from 'nanoid/non-secure'
272
- const nanoid = customAlphabet('1234567890abcdef', 10)
273
- user.id = nanoid()
274
- ```
275
-
276
- Не забудьте проверить риски коллизии вашего алфавита и длины
277
- [на нашем калькуляторе]. [`nanoid-dictionary`] содержит много популярных
278
- примеров альтернативных алфавитов.
279
-
280
- Алфавит должен содержать ≤256 символов. Иначе мы не сможем гарантировать
281
- непредсказуемость ID.
282
-
283
- [на нашем калькуляторе]: https://alex7kom.github.io/nano-nanoid-cc/
284
- [`nanoid-dictionary`]: https://github.com/CyberAP/nanoid-dictionary
285
-
286
-
287
- ### Смена генератора случайных чисел
288
-
289
- Функция `customRandom` позволяет создать свою функцию `nanoid` со своими
290
- генераторами случайных чисел, алфавитом и длинной ID.
291
-
292
- Например, можно использовать генератор c seed для повторяемости тестов.
293
-
294
- ```js
295
- import { customRandom } from 'nanoid'
296
-
297
- const rng = seedrandom(seed)
298
- const nanoid = customRandom('abcdef', 10, size => {
299
- return new Uint8Array(size).map(() => 256 * rng())
300
- })
301
-
302
- nanoid() //=> "fbaefaadeb"
303
- ```
304
-
305
- Функция в третьем аргументе `customRandom` должна принимать длину массива
306
- и возвращать нужный массив со случайными числами
307
-
308
- Если вы хотите заменить только генератор случайных чисел, но оставить
309
- URL-совместимый алфавит, то стандартный алфавит доступен
310
- в экспорте `urlAlphabet`.
311
-
312
- ```js
313
- const { customRandom, urlAlphabet } = require('nanoid')
314
- const nanoid = customRandom(urlAlphabet, 10, random)
315
- ```
316
-
317
- У асинхронной и небезопасной версий нет `customRandom`.
318
-
319
-
320
- ## Руководство
321
-
322
- ### IE
323
-
324
- Если вам нужна поддержка IE, потребуется включить [компиляцию `node_modules`]
325
- с помощью Babel и вручную убрать вендорный префикс у `crypto`.
326
-
327
- ```js
328
- // polyfills.js
329
- if (!window.crypto) {
330
- window.crypto = window.msCrypto
331
- }
332
- ```
333
-
334
- ```js
335
- import './polyfills.js'
336
- import { nanoid } from 'nanoid'
337
- ```
338
-
339
- [компиляцию `node_modules`]: https://developer.epages.com/blog/coding/how-to-transpile-node-modules-with-babel-and-webpack-in-a-monorepo/
340
-
341
-
342
- ### React
343
-
344
- Не используйте Nano ID для генерации свойства `key` в JSX. При каждом рендере
345
- `key` будет разный, что плохо скажется на производительности.
346
-
347
- ```jsx
348
- function Todos({ todos }) {
349
- return (
350
- <ul>
351
- {todos.map(todo => (
352
- <li key={nanoid()}> /* НЕ ДЕЛАЙТЕ ТАК */
353
- {todo.text}
354
- </li>
355
- ))}
356
- </ul>
357
- )
358
- }
359
- ```
360
-
361
- Подробнее об использовании свойства `key` читайте в
362
- [официальной документации React](https://ru.reactjs.org/docs/lists-and-keys.html#keys).
363
-
364
-
365
- ### HTML ID
366
-
367
- Если вы используете Nano ID для HTML-свойства `id`, то нужно в начало добавить
368
- какую-то строку — HTML ID не может начинаться с цифры, но Nano ID иногда может
369
- сгенерировать такие ID.
370
-
371
- ```jsx
372
- <input id={'id' + this.id} type="text" />
373
- ```
374
-
375
-
376
- ### React Native
377
-
378
- React Native не имеет встроенного аппаратного генератора случайных чисел.
379
- Полифил ниже работает в чистом React Native и в Expo начиная с версии 39.
380
-
381
- 1. Прочитайте документацию [`react-native-get-random-values`] и установите его.
382
- 2. Импортируйте эту библиотеку до импорта Nano ID.
383
-
384
- ```js
385
- import 'react-native-get-random-values'
386
- import { nanoid } from 'nanoid'
387
- ```
388
-
389
- [`react-native-get-random-values`]: https://github.com/LinusU/react-native-get-random-values
390
-
391
-
392
- ### Rollup
393
-
394
- Для Rollup понадобятся плагины [`@rollup/plugin-node-resolve`]
395
- и [`@rollup/plugin-replace`].
396
-
397
- ```js
398
- plugins: [
399
- nodeResolve({
400
- browser: true
401
- }),
402
- replace({
403
- 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
404
- })
405
- ]
406
- ```
407
-
408
- [`@rollup/plugin-node-resolve`]: https://github.com/rollup/plugins/tree/master/packages/node-resolve
409
- [`@rollup/plugin-replace`]: https://github.com/rollup/plugins/tree/master/packages/replace
410
-
411
-
412
- ### PouchDB и CouchDB
413
-
414
- В PouchDB и CouchDB, ID не могут начинаться с `_`. Добавьте к ID префикс,
415
- так как иногда Nano ID может сгенерировать ID начинающийся с `_`.
416
-
417
- Изменить стандартный ID можно через следующую опцию:
418
-
419
- ```js
420
- db.put({
421
- _id: 'id' + nanoid(),
422
-
423
- })
424
- ```
425
-
426
-
427
- ### Mongoose
428
-
429
- ```js
430
- const mySchema = new Schema({
431
- _id: {
432
- type: String,
433
- default: () => nanoid()
434
- }
435
- })
436
- ```
437
-
438
-
439
- ### Веб-воркеры
440
-
441
- Веб-воркеры не имеют доступа к аппаратному генератору случайных чисел.
442
-
443
- Аппаратный генератор нужен, в том числе, для непредсказуемости ID. Например,
444
- когда доступ к секретному документу защищён ссылкой с уникальным ID.
445
-
446
- Если вам не нужна непредсказуемость ID, то в Веб-воркере можно использовать
447
- небезопасный генератор ID.
448
-
449
- ```js
450
- import { nanoid } from 'nanoid/non-secure'
451
- nanoid() //=> "Uakgb_J5m9g-0JDMbcJqLJ"
452
- ```
453
-
454
-
455
- ### Терминал
456
-
457
- Можно сгенерировать уникальный ID прямо из терминала, вызвав `npx nanoid`.
458
- Для этого в системе должна быть только Node.js. `npx` сама скачает Nano ID,
459
- если его нет в системе.
460
-
461
- ```sh
462
- $ npx nanoid
463
- npx: installed 1 in 0.63s
464
- LZfXLFzPPR4NNrgjlWDxn
465
- ```
466
-
467
- Для смены алфавита или длины ID есть отдельный проект [`nanoid-cli`].
468
-
469
- [`nanoid-cli`]: https://github.com/twhitbeck/nanoid-cli
470
-
471
-
472
- ### Другие языки программирования
473
-
474
- Nano ID был портирован на множество языков. Это полезно, чтобы сервер и клиент
475
- генерировали ID по одной схеме.
476
-
477
- - [C#](https://github.com/codeyu/nanoid-net)
478
- - [C++](https://github.com/mcmikecreations/nanoid_cpp)
479
- - [Clojure и ClojureScript](https://github.com/zelark/nano-id)
480
- - [Crystal](https://github.com/mamantoha/nanoid.cr)
481
- - [Dart и Flutter](https://github.com/pd4d10/nanoid-dart)
482
- - [Deno](https://github.com/ianfabs/nanoid)
483
- - [Go](https://github.com/matoous/go-nanoid)
484
- - [Elixir](https://github.com/railsmechanic/nanoid)
485
- - [Haskell](https://github.com/4e6/nanoid-hs)
486
- - [Janet](https://sr.ht/~statianzo/janet-nanoid/)
487
- - [Java](https://github.com/aventrix/jnanoid)
488
- - [Nim](https://github.com/icyphox/nanoid.nim)
489
- - [Perl](https://github.com/tkzwtks/Nanoid-perl)
490
- - [PHP](https://github.com/hidehalo/nanoid-php)
491
- - [Python](https://github.com/puyuan/py-nanoid)
492
- со [словарями](https://pypi.org/project/nanoid-dictionary)
493
- - [Ruby](https://github.com/radeno/nanoid.rb)
494
- - [Rust](https://github.com/nikolay-govorov/nanoid)
495
- - [Swift](https://github.com/antiflasher/NanoID)
496
- - [V](https://github.com/invipal/nanoid)
497
-
498
- Для остальных сред можно использовать Nano ID [для терминала].
499
-
500
- [для терминала]: #терминал
501
-
502
-
503
- ## Инструменты
504
-
505
- - [Калькулятор длины ID] поможет подобрать оптимальную длину ID,
506
- в зависимости от частоты выдачи ID и нужной надёжности системы.
507
- - [`nanoid-dictionary`] с популярными алфавитами для [`customAlphabet`].
508
- - [`nanoid-good`] гарантирует, что в случайном ID не будет матерных слов.
509
-
510
- [калькулятор длины id]: https://zelark.github.io/nano-id-cc/
511
- [`nanoid-dictionary`]: https://github.com/CyberAP/nanoid-dictionary
512
- [`customalphabet`]: #смена-алфавита-или-длины
513
- [`nanoid-good`]: https://github.com/y-gagar1n/nanoid-good