123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- /*!
- * base64id v0.1.0
- */
- /**
- * Module dependencies
- */
- var crypto = require('crypto');
- /**
- * Constructor
- */
- var Base64Id = function() { };
- /**
- * Get random bytes
- *
- * Uses a buffer if available, falls back to crypto.randomBytes
- */
- Base64Id.prototype.getRandomBytes = function(bytes) {
- var BUFFER_SIZE = 4096
- var self = this;
-
- bytes = bytes || 12;
- if (bytes > BUFFER_SIZE) {
- return crypto.randomBytes(bytes);
- }
-
- var bytesInBuffer = parseInt(BUFFER_SIZE/bytes);
- var threshold = parseInt(bytesInBuffer*0.85);
- if (!threshold) {
- return crypto.randomBytes(bytes);
- }
- if (this.bytesBufferIndex == null) {
- this.bytesBufferIndex = -1;
- }
- if (this.bytesBufferIndex == bytesInBuffer) {
- this.bytesBuffer = null;
- this.bytesBufferIndex = -1;
- }
- // No buffered bytes available or index above threshold
- if (this.bytesBufferIndex == -1 || this.bytesBufferIndex > threshold) {
-
- if (!this.isGeneratingBytes) {
- this.isGeneratingBytes = true;
- crypto.randomBytes(BUFFER_SIZE, function(err, bytes) {
- self.bytesBuffer = bytes;
- self.bytesBufferIndex = 0;
- self.isGeneratingBytes = false;
- });
- }
-
- // Fall back to sync call when no buffered bytes are available
- if (this.bytesBufferIndex == -1) {
- return crypto.randomBytes(bytes);
- }
- }
-
- var result = this.bytesBuffer.slice(bytes*this.bytesBufferIndex, bytes*(this.bytesBufferIndex+1));
- this.bytesBufferIndex++;
-
- return result;
- }
- /**
- * Generates a base64 id
- *
- * (Original version from socket.io <http://socket.io>)
- */
- Base64Id.prototype.generateId = function () {
- var rand = Buffer.alloc(15); // multiple of 3 for base64
- if (!rand.writeInt32BE) {
- return Math.abs(Math.random() * Math.random() * Date.now() | 0).toString()
- + Math.abs(Math.random() * Math.random() * Date.now() | 0).toString();
- }
- this.sequenceNumber = (this.sequenceNumber + 1) | 0;
- rand.writeInt32BE(this.sequenceNumber, 11);
- if (crypto.randomBytes) {
- this.getRandomBytes(12).copy(rand);
- } else {
- // not secure for node 0.4
- [0, 4, 8].forEach(function(i) {
- rand.writeInt32BE(Math.random() * Math.pow(2, 32) | 0, i);
- });
- }
- return rand.toString('base64').replace(/\//g, '_').replace(/\+/g, '-');
- };
- /**
- * Export
- */
- exports = module.exports = new Base64Id();
|