twitst4tz

twitter statistics web application
Log | Files | Refs | README | LICENSE

base64id.js (2365B)


      1 /*!
      2  * base64id v0.1.0
      3  */
      4 
      5 /**
      6  * Module dependencies
      7  */
      8 
      9 var crypto = require('crypto');
     10 
     11 /**
     12  * Constructor
     13  */
     14 
     15 var Base64Id = function() { };
     16 
     17 /**
     18  * Get random bytes
     19  *
     20  * Uses a buffer if available, falls back to crypto.randomBytes
     21  */
     22 
     23 Base64Id.prototype.getRandomBytes = function(bytes) {
     24 
     25   var BUFFER_SIZE = 4096
     26   var self = this;  
     27   
     28   bytes = bytes || 12;
     29 
     30   if (bytes > BUFFER_SIZE) {
     31     return crypto.randomBytes(bytes);
     32   }
     33   
     34   var bytesInBuffer = parseInt(BUFFER_SIZE/bytes);
     35   var threshold = parseInt(bytesInBuffer*0.85);
     36 
     37   if (!threshold) {
     38     return crypto.randomBytes(bytes);
     39   }
     40 
     41   if (this.bytesBufferIndex == null) {
     42      this.bytesBufferIndex = -1;
     43   }
     44 
     45   if (this.bytesBufferIndex == bytesInBuffer) {
     46     this.bytesBuffer = null;
     47     this.bytesBufferIndex = -1;
     48   }
     49 
     50   // No buffered bytes available or index above threshold
     51   if (this.bytesBufferIndex == -1 || this.bytesBufferIndex > threshold) {
     52      
     53     if (!this.isGeneratingBytes) {
     54       this.isGeneratingBytes = true;
     55       crypto.randomBytes(BUFFER_SIZE, function(err, bytes) {
     56         self.bytesBuffer = bytes;
     57         self.bytesBufferIndex = 0;
     58         self.isGeneratingBytes = false;
     59       }); 
     60     }
     61     
     62     // Fall back to sync call when no buffered bytes are available
     63     if (this.bytesBufferIndex == -1) {
     64       return crypto.randomBytes(bytes);
     65     }
     66   }
     67   
     68   var result = this.bytesBuffer.slice(bytes*this.bytesBufferIndex, bytes*(this.bytesBufferIndex+1)); 
     69   this.bytesBufferIndex++; 
     70   
     71   return result;
     72 }
     73 
     74 /**
     75  * Generates a base64 id
     76  *
     77  * (Original version from socket.io <http://socket.io>)
     78  */
     79 
     80 Base64Id.prototype.generateId = function () {
     81   var rand = Buffer.alloc(15); // multiple of 3 for base64
     82   if (!rand.writeInt32BE) {
     83     return Math.abs(Math.random() * Math.random() * Date.now() | 0).toString()
     84       + Math.abs(Math.random() * Math.random() * Date.now() | 0).toString();
     85   }
     86   this.sequenceNumber = (this.sequenceNumber + 1) | 0;
     87   rand.writeInt32BE(this.sequenceNumber, 11);
     88   if (crypto.randomBytes) {
     89     this.getRandomBytes(12).copy(rand);
     90   } else {
     91     // not secure for node 0.4
     92     [0, 4, 8].forEach(function(i) {
     93       rand.writeInt32BE(Math.random() * Math.pow(2, 32) | 0, i);
     94     });
     95   }
     96   return rand.toString('base64').replace(/\//g, '_').replace(/\+/g, '-');
     97 };
     98 
     99 /**
    100  * Export
    101  */
    102 
    103 exports = module.exports = new Base64Id();