You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							102 lines
						
					
					
						
							1.9 KiB
						
					
					
				
			
		
		
	
	
							102 lines
						
					
					
						
							1.9 KiB
						
					
					
				| /*!
 | |
|  * random-bytes
 | |
|  * Copyright(c) 2016 Douglas Christopher Wilson
 | |
|  * MIT Licensed
 | |
|  */
 | |
| 
 | |
| 'use strict'
 | |
| 
 | |
| /**
 | |
|  * Module dependencies.
 | |
|  * @private
 | |
|  */
 | |
| 
 | |
| var crypto = require('crypto')
 | |
| 
 | |
| /**
 | |
|  * Module variables.
 | |
|  * @private
 | |
|  */
 | |
| 
 | |
| var generateAttempts = crypto.randomBytes === crypto.pseudoRandomBytes ? 1 : 3
 | |
| 
 | |
| /**
 | |
|  * Module exports.
 | |
|  * @public
 | |
|  */
 | |
| 
 | |
| module.exports = randomBytes
 | |
| module.exports.sync = randomBytesSync
 | |
| 
 | |
| /**
 | |
|  * Generates strong pseudo-random bytes.
 | |
|  *
 | |
|  * @param {number} size
 | |
|  * @param {function} [callback]
 | |
|  * @return {Promise}
 | |
|  * @public
 | |
|  */
 | |
| 
 | |
| function randomBytes(size, callback) {
 | |
|   // validate callback is a function, if provided
 | |
|   if (callback !== undefined && typeof callback !== 'function') {
 | |
|     throw new TypeError('argument callback must be a function')
 | |
|   }
 | |
| 
 | |
|   // require the callback without promises
 | |
|   if (!callback && !global.Promise) {
 | |
|     throw new TypeError('argument callback is required')
 | |
|   }
 | |
| 
 | |
|   if (callback) {
 | |
|     // classic callback style
 | |
|     return generateRandomBytes(size, generateAttempts, callback)
 | |
|   }
 | |
| 
 | |
|   return new Promise(function executor(resolve, reject) {
 | |
|     generateRandomBytes(size, generateAttempts, function onRandomBytes(err, str) {
 | |
|       if (err) return reject(err)
 | |
|       resolve(str)
 | |
|     })
 | |
|   })
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Generates strong pseudo-random bytes sync.
 | |
|  *
 | |
|  * @param {number} size
 | |
|  * @return {Buffer}
 | |
|  * @public
 | |
|  */
 | |
| 
 | |
| function randomBytesSync(size) {
 | |
|   var err = null
 | |
| 
 | |
|   for (var i = 0; i < generateAttempts; i++) {
 | |
|     try {
 | |
|       return crypto.randomBytes(size)
 | |
|     } catch (e) {
 | |
|       err = e
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   throw err
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Generates strong pseudo-random bytes.
 | |
|  *
 | |
|  * @param {number} size
 | |
|  * @param {number} attempts
 | |
|  * @param {function} callback
 | |
|  * @private
 | |
|  */
 | |
| 
 | |
| function generateRandomBytes(size, attempts, callback) {
 | |
|   crypto.randomBytes(size, function onRandomBytes(err, buf) {
 | |
|     if (!err) return callback(null, buf)
 | |
|     if (!--attempts) return callback(err)
 | |
|     setTimeout(generateRandomBytes.bind(null, size, attempts, callback), 10)
 | |
|   })
 | |
| }
 |