| 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();
 |