source: imaps-frontend/node_modules/nanoid/index.browser.cjs@ 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: 2.8 KB
Line 
1// This file replaces `index.js` in bundlers like webpack or Rollup,
2// according to `browser` config in `package.json`.
3
4let { urlAlphabet } = require('./url-alphabet/index.cjs')
5
6let random = bytes => crypto.getRandomValues(new Uint8Array(bytes))
7
8let customRandom = (alphabet, defaultSize, getRandom) => {
9 // First, a bitmask is necessary to generate the ID. The bitmask makes bytes
10 // values closer to the alphabet size. The bitmask calculates the closest
11 // `2^31 - 1` number, which exceeds the alphabet size.
12 // For example, the bitmask for the alphabet size 30 is 31 (00011111).
13 // `Math.clz32` is not used, because it is not available in browsers.
14 let mask = (2 << (Math.log(alphabet.length - 1) / Math.LN2)) - 1
15 // Though, the bitmask solution is not perfect since the bytes exceeding
16 // the alphabet size are refused. Therefore, to reliably generate the ID,
17 // the random bytes redundancy has to be satisfied.
18
19 // Note: every hardware random generator call is performance expensive,
20 // because the system call for entropy collection takes a lot of time.
21 // So, to avoid additional system calls, extra bytes are requested in advance.
22
23 // Next, a step determines how many random bytes to generate.
24 // The number of random bytes gets decided upon the ID size, mask,
25 // alphabet size, and magic number 1.6 (using 1.6 peaks at performance
26 // according to benchmarks).
27
28 // `-~f => Math.ceil(f)` if f is a float
29 // `-~i => i + 1` if i is an integer
30 let step = -~((1.6 * mask * defaultSize) / alphabet.length)
31
32 return (size = defaultSize) => {
33 let id = ''
34 while (true) {
35 let bytes = getRandom(step)
36 // A compact alternative for `for (var i = 0; i < step; i++)`.
37 let j = step | 0
38 while (j--) {
39 // Adding `|| ''` refuses a random byte that exceeds the alphabet size.
40 id += alphabet[bytes[j] & mask] || ''
41 if (id.length === size) return id
42 }
43 }
44 }
45}
46
47let customAlphabet = (alphabet, size = 21) =>
48 customRandom(alphabet, size, random)
49
50let nanoid = (size = 21) =>
51 crypto.getRandomValues(new Uint8Array(size)).reduce((id, byte) => {
52 // It is incorrect to use bytes exceeding the alphabet size.
53 // The following mask reduces the random byte in the 0-255 value
54 // range to the 0-63 value range. Therefore, adding hacks, such
55 // as empty string fallback or magic numbers, is unneccessary because
56 // the bitmask trims bytes down to the alphabet size.
57 byte &= 63
58 if (byte < 36) {
59 // `0-9a-z`
60 id += byte.toString(36)
61 } else if (byte < 62) {
62 // `A-Z`
63 id += (byte - 26).toString(36).toUpperCase()
64 } else if (byte > 62) {
65 id += '-'
66 } else {
67 id += '_'
68 }
69 return id
70 }, '')
71
72module.exports = { nanoid, customAlphabet, customRandom, urlAlphabet, random }
Note: See TracBrowser for help on using the repository browser.