crypt.js
 1  (function() {
 2    var base64map
 3        = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
 4  
 5    crypt = {
 6      // Bit-wise rotation left
 7      rotl: function(n, b) {
 8        return (n << b) | (n >>> (32 - b));
 9      },
10  
11      // Bit-wise rotation right
12      rotr: function(n, b) {
13        return (n << (32 - b)) | (n >>> b);
14      },
15  
16      // Swap big-endian to little-endian and vice versa
17      endian: function(n) {
18        // If number given, swap endian
19        if (n.constructor == Number) {
20          return crypt.rotl(n, 8) & 0x00FF00FF | crypt.rotl(n, 24) & 0xFF00FF00;
21        }
22  
23        // Else, assume array and swap all items
24        for (var i = 0; i < n.length; i++)
25          n[i] = crypt.endian(n[i]);
26        return n;
27      },
28  
29      // Generate an array of any length of random bytes
30      randomBytes: function(n) {
31        for (var bytes = []; n > 0; n--)
32          bytes.push(Math.floor(Math.random() * 256));
33        return bytes;
34      },
35  
36      // Convert a byte array to big-endian 32-bit words
37      bytesToWords: function(bytes) {
38        for (var words = [], i = 0, b = 0; i < bytes.length; i++, b += 8)
39          words[b >>> 5] |= bytes[i] << (24 - b % 32);
40        return words;
41      },
42  
43      // Convert big-endian 32-bit words to a byte array
44      wordsToBytes: function(words) {
45        for (var bytes = [], b = 0; b < words.length * 32; b += 8)
46          bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF);
47        return bytes;
48      },
49  
50      // Convert a byte array to a hex string
51      bytesToHex: function(bytes) {
52        for (var hex = [], i = 0; i < bytes.length; i++) {
53          hex.push((bytes[i] >>> 4).toString(16));
54          hex.push((bytes[i] & 0xF).toString(16));
55        }
56        return hex.join('');
57      },
58  
59      // Convert a hex string to a byte array
60      hexToBytes: function(hex) {
61        for (var bytes = [], c = 0; c < hex.length; c += 2)
62          bytes.push(parseInt(hex.substr(c, 2), 16));
63        return bytes;
64      },
65  
66      // Convert a byte array to a base-64 string
67      bytesToBase64: function(bytes) {
68        for (var base64 = [], i = 0; i < bytes.length; i += 3) {
69          var triplet = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];
70          for (var j = 0; j < 4; j++)
71            if (i * 8 + j * 6 <= bytes.length * 8)
72              base64.push(base64map.charAt((triplet >>> 6 * (3 - j)) & 0x3F));
73            else
74              base64.push('=');
75        }
76        return base64.join('');
77      },
78  
79      // Convert a base-64 string to a byte array
80      base64ToBytes: function(base64) {
81        // Remove non-base-64 characters
82        base64 = base64.replace(/[^A-Z0-9+\/]/ig, '');
83  
84        for (var bytes = [], i = 0, imod4 = 0; i < base64.length;
85            imod4 = ++i % 4) {
86          if (imod4 == 0) continue;
87          bytes.push(((base64map.indexOf(base64.charAt(i - 1))
88              & (Math.pow(2, -2 * imod4 + 8) - 1)) << (imod4 * 2))
89              | (base64map.indexOf(base64.charAt(i)) >>> (6 - imod4 * 2)));
90        }
91        return bytes;
92      }
93    };
94  
95    module.exports = crypt;
96  })();