UNPKG

3 kBJavaScriptView Raw
1'use strict'
2
3function oldBrowser () {
4 throw new Error('secure random number generation not supported by this browser\nuse chrome, FireFox or Internet Explorer 11')
5}
6var safeBuffer = require('safe-buffer')
7var randombytes = require('randombytes')
8var Buffer = safeBuffer.Buffer
9var kBufferMaxLength = safeBuffer.kMaxLength
10var crypto = global.crypto || global.msCrypto
11var kMaxUint32 = Math.pow(2, 32) - 1
12function assertOffset (offset, length) {
13 if (typeof offset !== 'number' || offset !== offset) { // eslint-disable-line no-self-compare
14 throw new TypeError('offset must be a number')
15 }
16
17 if (offset > kMaxUint32 || offset < 0) {
18 throw new TypeError('offset must be a uint32')
19 }
20
21 if (offset > kBufferMaxLength || offset > length) {
22 throw new RangeError('offset out of range')
23 }
24}
25
26function assertSize (size, offset, length) {
27 if (typeof size !== 'number' || size !== size) { // eslint-disable-line no-self-compare
28 throw new TypeError('size must be a number')
29 }
30
31 if (size > kMaxUint32 || size < 0) {
32 throw new TypeError('size must be a uint32')
33 }
34
35 if (size + offset > length || size > kBufferMaxLength) {
36 throw new RangeError('buffer too small')
37 }
38}
39if ((crypto && crypto.getRandomValues) || !process.browser) {
40 exports.randomFill = randomFill
41 exports.randomFillSync = randomFillSync
42} else {
43 exports.randomFill = oldBrowser
44 exports.randomFillSync = oldBrowser
45}
46function randomFill (buf, offset, size, cb) {
47 if (!Buffer.isBuffer(buf) && !(buf instanceof global.Uint8Array)) {
48 throw new TypeError('"buf" argument must be a Buffer or Uint8Array')
49 }
50
51 if (typeof offset === 'function') {
52 cb = offset
53 offset = 0
54 size = buf.length
55 } else if (typeof size === 'function') {
56 cb = size
57 size = buf.length - offset
58 } else if (typeof cb !== 'function') {
59 throw new TypeError('"cb" argument must be a function')
60 }
61 assertOffset(offset, buf.length)
62 assertSize(size, offset, buf.length)
63 return actualFill(buf, offset, size, cb)
64}
65
66function actualFill (buf, offset, size, cb) {
67 if (process.browser) {
68 var ourBuf = buf.buffer
69 var uint = new Uint8Array(ourBuf, offset, size)
70 crypto.getRandomValues(uint)
71 if (cb) {
72 process.nextTick(function () {
73 cb(null, buf)
74 })
75 return
76 }
77 return buf
78 }
79 if (cb) {
80 randombytes(size, function (err, bytes) {
81 if (err) {
82 return cb(err)
83 }
84 bytes.copy(buf, offset)
85 cb(null, buf)
86 })
87 return
88 }
89 var bytes = randombytes(size)
90 bytes.copy(buf, offset)
91 return buf
92}
93function randomFillSync (buf, offset, size) {
94 if (typeof offset === 'undefined') {
95 offset = 0
96 }
97 if (!Buffer.isBuffer(buf) && !(buf instanceof global.Uint8Array)) {
98 throw new TypeError('"buf" argument must be a Buffer or Uint8Array')
99 }
100
101 assertOffset(offset, buf.length)
102
103 if (size === undefined) size = buf.length - offset
104
105 assertSize(size, offset, buf.length)
106
107 return actualFill(buf, offset, size)
108}