Skip to content

Commit fe85195

Browse files
committed
Strings using Math.random
1 parent 3c05fa8 commit fe85195

File tree

3 files changed

+93
-39
lines changed

3 files changed

+93
-39
lines changed

dist/lib/entropy.js

Lines changed: 53 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,17 @@ var _lcm2 = _interopRequireDefault(_lcm);
2222

2323
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
2424

25-
var crypto = require('crypto');
26-
2725
var log2 = _log4.default;
2826
var log10 = _log2.default;
2927
var log2_10 = log2(10);
3028

29+
var endianByteNum = function () {
30+
var buf32 = new Uint32Array(1);
31+
var buf8 = new Uint8Array(buf32.buffer);
32+
buf32[0] = 0xff;
33+
return buf8[0] === 0xff ? [2, 3, 4, 5, 6, 7] : [0, 1, 2, 3, 6, 7];
34+
}();
35+
3136
var bits = function bits(total, risk) {
3237
if (total == 0) {
3338
return 0;
@@ -69,32 +74,22 @@ var bitsWithPowers = function bitsWithPowers(tPower, rPower) {
6974
return N;
7075
};
7176

72-
var randomString = function randomString(bits, charSet) {
73-
if (!_charSet2.default.isValid(charSet)) {
74-
throw new Error('Invalid CharSet');
75-
}
76-
77-
var count = Math.ceil(bits / charSet.entropyPerChar);
78-
if (count <= 0) {
79-
return '';
80-
}
81-
82-
var bytes = randomBytes(count, charSet);
77+
var randomString = function randomString(entropy, charSet) {
78+
var crypto = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
8379

84-
return randomStringWithBytes(bits, charSet, bytes);
80+
var bytes = crypto ? cryptoBytes(entropy, charSet) : randomBytes(entropy, charSet);
81+
return randomStringWithBytes(entropy, charSet, bytes);
8582
};
8683

87-
var randomStringWithBytes = function randomStringWithBytes(bits, charSet, bytes) {
84+
var randomStringWithBytes = function randomStringWithBytes(entropy, charSet, bytes) {
8885
if (!_charSet2.default.isValid(charSet)) {
89-
console.log('WTF?');
9086
throw new Error('Invalid CharSet');
9187
}
92-
93-
if (bits <= 0) {
88+
if (entropy <= 0) {
9489
return '';
9590
}
9691

97-
var count = Math.ceil(bits / charSet.entropyPerChar);
92+
var count = Math.ceil(entropy / charSet.entropyPerChar);
9893
if (count <= 0) {
9994
return '';
10095
}
@@ -152,10 +147,45 @@ var randomStringWithBytes = function randomStringWithBytes(bits, charSet, bytes)
152147
return string;
153148
};
154149

155-
var randomBytes = function randomBytes(count, charSet) {
150+
var bytesNeeded = function bytesNeeded(entropy, charSet) {
151+
if (!_charSet2.default.isValid(charSet)) {
152+
throw new Error('Invalid CharSet');
153+
}
154+
var count = Math.ceil(entropy / charSet.entropyPerChar);
155+
if (count <= 0) {
156+
return 0;
157+
}
158+
156159
var bytesPerSlice = charSet.entropyPerChar / 8;
157-
var bytesNeeded = Math.ceil(count * bytesPerSlice);
158-
return Buffer.from(crypto.randomBytes(bytesNeeded));
160+
return Math.ceil(count * bytesPerSlice);
161+
};
162+
163+
var cryptoBytes = function cryptoBytes(entropy, charSet) {
164+
var crypto = require('crypto');
165+
return Buffer.from(crypto.randomBytes(bytesNeeded(entropy, charSet)));
166+
};
167+
168+
var randomBytes = function randomBytes(entropy, charSet) {
169+
var byteCount = bytesNeeded(entropy, charSet);
170+
var randCount = Math.ceil(byteCount / 6);
171+
172+
var buffer = new Buffer(byteCount);
173+
var dataView = new DataView(new ArrayBuffer(8));
174+
for (var rNum = 0; rNum < randCount; rNum++) {
175+
dataView.setFloat64(0, Math.random());
176+
for (var n = 0; n < 6; n++) {
177+
var fByteNum = endianByteNum[n];
178+
var bByteNum = 6 * rNum + n;
179+
bufferByte(buffer, bByteNum, fByteNum, byteCount, dataView);
180+
}
181+
}
182+
return buffer;
183+
};
184+
185+
var bufferByte = function bufferByte(buffer, bByte, nByte, byteCount, dataView) {
186+
if (bByte < byteCount) {
187+
buffer[bByte] = dataView.getUint8(nByte);
188+
}
159189
};
160190

161191
var ndx64 = function ndx64(chunk, slice, bytes) {
@@ -209,6 +239,7 @@ exports.default = {
209239
bitsWithPowers: bitsWithPowers,
210240
randomString: randomString,
211241
randomStringWithBytes: randomStringWithBytes,
242+
bytesNeeded: bytesNeeded,
212243

213244
charSet64: _charSet2.default.charSet64,
214245
charSet32: _charSet2.default.charSet32,

dist/lib/lcm.js

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,15 @@
33
Object.defineProperty(exports, "__esModule", {
44
value: true
55
});
6-
76
var gcd = function gcd(a, b) {
87
while (b != 0) {
9-
var h = a;
10-
a = b;
11-
b = h % b;
12-
// (a, b) = (b, a % b)
8+
var _ref = [b, a % b];
9+
a = _ref[0];
10+
b = _ref[1];
1311
}
1412
return Math.abs(a);
1513
};
1614

17-
// const lcm = (a, b) => {
18-
// return (a / gcd(a, b)) * b
19-
// }
20-
2115
exports.default = function (a, b) {
2216
return a / gcd(a, b) * b;
2317
};

lib/entropy.js

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
1-
const crypto = require('crypto')
2-
31
import CharSet from './charSet'
42
import lcm from './lcm'
53

64
const log2 = Math.log2
75
const log10 = Math.log10
86
const log2_10 = log2(10)
97

8+
const endianByteNum = (() => {
9+
const buf32 = new Uint32Array(1)
10+
const buf8 = new Uint8Array(buf32.buffer)
11+
buf32[0] = 0xff
12+
return (buf8[0] === 0xff) ? [2,3,4,5,6,7] : [0,1,2,3,6,7]
13+
})()
14+
1015
const bits = (total, risk) => {
1116
if (total == 0) { return 0 }
1217

@@ -47,18 +52,18 @@ const bitsWithPowers = (tPower, rPower) => {
4752
return N
4853
}
4954

50-
const randomString = (bits, charSet) => {
51-
const bytes = cryptoBytes(bits, charSet)
52-
return randomStringWithBytes(bits, charSet, bytes)
55+
const randomString = (entropy, charSet, crypto = true) => {
56+
const bytes = crypto ? cryptoBytes(entropy, charSet) : randomBytes(entropy, charSet)
57+
return randomStringWithBytes(entropy, charSet, bytes)
5358
}
5459

55-
const randomStringWithBytes = (bits, charSet, bytes) => {
60+
const randomStringWithBytes = (entropy, charSet, bytes) => {
5661
if (!CharSet.isValid(charSet)) {
5762
throw new Error('Invalid CharSet')
5863
}
59-
if (bits <= 0) { return '' }
64+
if (entropy <= 0) { return '' }
6065

61-
const count = Math.ceil(bits / charSet.entropyPerChar)
66+
const count = Math.ceil(entropy / charSet.entropyPerChar)
6267
if (count <= 0) { return '' }
6368

6469
const needed = Math.ceil(count * (charSet.entropyPerChar/8))
@@ -123,9 +128,33 @@ const bytesNeeded = (entropy, charSet) => {
123128
}
124129

125130
const cryptoBytes = (entropy, charSet) => {
131+
const crypto = require('crypto')
126132
return Buffer.from(crypto.randomBytes(bytesNeeded(entropy, charSet)))
127133
}
128134

135+
const randomBytes = (entropy, charSet) => {
136+
const byteCount = bytesNeeded(entropy, charSet)
137+
const randCount = Math.ceil(byteCount / 6)
138+
139+
const buffer = new Buffer(byteCount)
140+
var dataView = new DataView(new ArrayBuffer(8))
141+
for (let rNum = 0; rNum < randCount; rNum++) {
142+
dataView.setFloat64(0, Math.random())
143+
for (let n = 0; n < 6; n++) {
144+
let fByteNum = endianByteNum[n]
145+
let bByteNum = 6*rNum + n
146+
bufferByte(buffer, bByteNum, fByteNum, byteCount, dataView)
147+
}
148+
}
149+
return buffer
150+
}
151+
152+
const bufferByte = (buffer, bByte, nByte, byteCount, dataView) => {
153+
if (bByte < byteCount) {
154+
buffer[bByte] = dataView.getUint8(nByte)
155+
}
156+
}
157+
129158
const ndx64 = (chunk, slice, bytes) => {
130159
return ndxGen(chunk, slice, bytes, 6)
131160
}

0 commit comments

Comments
 (0)