Skip to content

Commit 934c8bb

Browse files
committed
Entropy.bits class method
1 parent 56d3a99 commit 934c8bb

16 files changed

+320
-141
lines changed

README.md

+70-74
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,11 @@ Run any of the examples in the `examples` directory by:
4949
Generate a potential of _1 million_ random strings with _1 in a billion_ chance of repeat:
5050

5151
```js
52-
const {Random, Entropy} = require('entropy-string')
52+
const { Entropy } = require('entropy-string')
5353

54-
const random = new Random()
5554
const bits = Entropy.bits(1e6, 1e9)
56-
57-
const string = random.string(bits)
55+
const entropy = new Entropy()
56+
const string = entropy.string(bits)
5857
```
5958

6059
> pbbnBD4MQ3rbRN
@@ -64,58 +63,56 @@ See [Real Need](#RealNeed) for description of what entropy bits represents.
6463
`EntropyString` uses predefined `charset32` characters by default (see [Character Sets](#CharacterSets)). To get a random hexadecimal string with the same entropy `bits` as above:
6564

6665
```js
67-
const {Random, Entropy, charSet16} = require('entropy-string')
66+
const { Entropy, charSet16 } = require('entropy-string')
6867

69-
const random = new Random(charSet16)
7068
const bits = Entropy.bits(1e6, 1e9)
71-
72-
const string = random.string(bits)
69+
const entropy = new Entropy(charSet16)
70+
const string = entropy.string(bits)
7371
```
7472

7573
> 878114ac513a538e22
7674
7775
Custom characters may be specified. Using uppercase hexadecimal characters:
7876

7977
```js
80-
const {Random, Entropy} = require('entropy-string')
78+
const { Entropy } = require('entropy-string')
8179

82-
const random = new Random('0123456789ABCDEF')
8380
const bits = Entropy.bits(1e6, 1e9)
84-
85-
const string = random.string(bits)
81+
const entropy = new Entropy('0123456789ABCDEF')
82+
const string = entropy.string(bits)
8683
```
8784

8885
> 16E26779479356B516
8986
9087
Convenience functions `smallID`, `mediumID`, `largeID`, `sessionID` and `token` provide random strings for various predefined bits of entropy. For example, a small id represents a potential of 30 strings with a 1 in a million chance of repeat:
9188

9289
```js
93-
const {Random} = require('entropy-string')
90+
const {Entropy} = require('entropy-string')
9491

95-
const random = new Random()
96-
const string = random.smallID()
92+
const entropy = new Entropy()
93+
const string = entropy.smallID()
9794
```
9895

9996
> DpTQqg
10097
10198
Or, to generate an OWASP session ID:
10299

103100
```js
104-
const {Random} = require('entropy-string')
101+
const {Entropy} = require('entropy-string')
105102

106-
const random = new Random()
107-
const string = random.sessionID()
103+
const entropy = new Entropy()
104+
const string = entropy.sessionID()
108105
```
109106

110107
> nqqBt2P669nmjPQRqh4NtmTPn9
111108
112109
Or perhaps you need an 256-bit token using [RFC 4648](https://tools.ietf.org/html/rfc4648#section-5) file system and URL safe characters:
113110
```js
114-
const {Random, Entropy, charSet64} = require('entropy-string')
111+
const {Entropy, Entropy, charSet64} = require('entropy-string')
115112

116-
const random = new Random(charSet64)
113+
const entropy = new Entropy(charSet64)
117114

118-
const string = random.token()
115+
const string = entropy.token()
119116
```
120117

121118
> t-Z8b9FLvpc-roln2BZnGYLZAX_pn5U7uO_cbfldsIt
@@ -181,14 +178,13 @@ How do you address this need using a library designed to generate strings of spe
181178
Let's use `entropy-string` to help this developer generate 5 hexadecimal IDs from a pool of a potentail 10,000 IDs with a 1 in a milllion chance of a repeat:
182179

183180
```js
184-
const {Random, Entropy, charSet16} = require('entropy-string')
181+
const { Entropy, charSet16 } = require('entropy-string')
185182

186183
const bits = Entropy.bits(10000, 1000000)
187-
const random = new Random(charSet16)
188-
184+
const entropy = new Entropy(charSet16)
189185
const strings = Array()
190186
for (let i = 0; i < 5; i++) {
191-
string = random.string(bits)
187+
string = entropy.string(bits)
192188
strings.push(string)
193189
}
194190
```
@@ -204,13 +200,13 @@ Examining the above code,
204200
is used to determine how much entropy is needed to satisfy the probabilistic uniqueness of a **1 in a million** risk of repeat in a total of **10,000** potential strings. We didn't print the result, but if you did you'd see it's about **45.51** bits. Then
205201

206202
```js
207-
const random = new Random(charSet16)
203+
const entropy = new Entropy(charSet16)
208204
```
209205

210-
creates a `Random` instance configured to generated strings using the predefined hexadecimal characters provided by `charSet16`. Finally
206+
creates a `Entropy` instance configured to generated strings using the predefined hexadecimal characters provided by `charSet16`. Finally
211207

212208
```js
213-
const string = random.string(bits)
209+
const string = entropy.string(bits)
214210
```
215211

216212
is used to actually generate a random string of the specified entropy.
@@ -225,14 +221,14 @@ Given that the strings are 12 hexadecimals long, each string actually has an inf
225221

226222
In [Real Need](#RealNeed) our developer used hexadecimal characters for the strings. Let's look at using other characters instead.
227223

228-
We'll start with using 32 characters. What 32 characters, you ask? The [Character Sets](#CharacterSets) section discusses the predefined characters available in `entropy-string` and the [Custom Characters](#CustomCharacters) section describes how you can use whatever characters you want. By default, `entropy-string` uses `charSet32` characters, so we don't need to pass that parameter into `new Random()`.
224+
We'll start with using 32 characters. What 32 characters, you ask? The [Character Sets](#CharacterSets) section discusses the predefined characters available in `entropy-string` and the [Custom Characters](#CustomCharacters) section describes how you can use whatever characters you want. By default, `entropy-string` uses `charSet32` characters, so we don't need to pass that parameter into `new Entropy()`.
229225

230226
```js
231-
const {Random, Entropy} = require('entropy-string')
227+
const { Entropy } = require('entropy-string')
232228

233-
const random = new Random()
234229
const bits = Entropy.bits(10000, 1e6)
235-
const string = random.string(bits)
230+
const entropy = new Entropy()
231+
const string = entropy.string(bits)
236232
```
237233

238234
> String: MD8r3BpTH3
@@ -242,20 +238,20 @@ We're using the same `Entropy.bits` calculation since we haven't changed the num
242238
As another example, let's assume we need to ensure the names of a handful of items are unique. Let's say 30 items. And suppose we decide we can live with a 1 in 100,000 probability of collision (we're just futzing with some coding ideas). Using the predefined provided hex characters:
243239

244240
```js
245-
const {Random, Entropy, charSet16, charSet4} = require('entropy-string')
241+
const { Entropy, charSet16, charSet4 } = require('entropy-string')
246242

247-
const random = new Random(charSet16)
248243
const bits = Entropy.bits(30, 100000)
249-
const string = random.string(bits)
244+
const entropy = new Entropy(charSet16)
245+
const string = entropy.string(bits)
250246
```
251247

252248
> String: dbf40a6
253249
254-
Using the same `Random` instance, we can switch to the predefined `charSet4` characters and generate a string of the same amount of entropy:
250+
Using the same `Entropy` instance, we can switch to the predefined `charSet4` characters and generate a string of the same amount of entropy:
255251

256252
```js
257-
random.use(charSet4)
258-
string = random.string(bits)
253+
entropy.use(charSet4)
254+
string = entropy.string(bits)
259255
```
260256

261257
> String: CAATAGTGGACTG
@@ -265,33 +261,33 @@ Okay, we probably wouldn't use 4 characters (and what's up with those characters
265261
Suppose we have a more extreme need. We want less than a 1 in a trillion chance that 10 billion base 32 strings repeat. Let's see, our total (10 billion) is 10<sup>10</sup> and our risk (1 trillion) is 10<sup>12</sup>, so:
266262

267263
```js
268-
const {Random, Entropy} = require('entropy-string')
264+
const { Entropy } = require('entropy-string')
269265

270-
const random = new Random()
271266
const bits = Entropy.bits(1e10, 1e12)
272-
const string = random.string(bits)
267+
const entropy = new Entropy()
268+
const string = entropy.string(bits)
273269
```
274270

275271
> String: 4J86pbFG9BqdBjTLfD3rt6
276272
277273
Finally, let say we're generating session IDs. Since session IDs are ephemeral, we aren't interested in uniqueness per se, but in ensuring our IDs aren't predictable since we can't have the bad guys guessing a valid session ID. In this case, we're using entropy as a measure of unpredictability of the IDs. Rather than calculate our entropy, we declare it as 128 bits (since we read on the OWASP web site that session IDs should be 128 bits).
278274

279275
```js
280-
const {Random} = require('entropy-string')
276+
const {Entropy} = require('entropy-string')
281277

282-
const random = new Random()
283-
const string = random.string(128)
278+
const entropy = new Entropy()
279+
const string = entropy.string(128)
284280
```
285281

286282
> String: Rm9gDFn6Q9DJ9rbrtrttBjR97r
287283
288284
Since session ID are such an important need, `entropy-string` provides a convenience function for generating them:
289285

290286
```js
291-
const {Random, charSet64} = require('entropy-string')
287+
const {Entropy, charSet64} = require('entropy-string')
292288

293-
const random = new Random(charSet64)
294-
const string = random.sessionID()
289+
const entropy = new Entropy(charSet64)
290+
const string = entropy.sessionID()
295291

296292
```
297293

@@ -345,47 +341,47 @@ You may, of course, want to choose the characters used, which is covered next in
345341
Being able to easily generate random strings is great, but what if you want to specify your own characters. For example, suppose you want to visualize flipping a coin to produce entropy of 10 bits.
346342

347343
```js
348-
const {Random, charSet2} = require('entropy-string')
344+
const {Entropy, charSet2} = require('entropy-string')
349345

350-
const random = new Random(charSet2)
351-
let flips = random.string(10)
346+
const entropy = new Entropy(charSet2)
347+
let flips = entropy.string(10)
352348
```
353349

354350
> flips: 1111001011
355351
356352
The resulting string of __0__'s and __1__'s doesn't look quite right. Perhaps you want to use the characters __H__ and __T__ instead.
357353

358354
```js
359-
random.useChars('HT')
360-
flips = random.string(10)
355+
entropy.useChars('HT')
356+
flips = entropy.string(10)
361357
```
362358

363359
> flips: THHTHTTHHT
364360
365361
As another example, we saw in [Character Sets](#CharacterSets) the predefined hex characters for `charSet16` are lowercase. Suppose you like uppercase hexadecimal letters instead.
366362

367363
```js
368-
const {Random} = require('entropy-string')
364+
const {Entropy} = require('entropy-string')
369365

370-
const random = new Random('0123456789ABCDEF')
371-
const string = random.string(48)
366+
const entropy = new Entropy('0123456789ABCDEF')
367+
const string = entropy.string(48)
372368

373369
```
374370

375371
> string: 08BB82C0056A
376372
377-
The `Random` constructor allows for three separate cases:
373+
The `Entropy` constructor allows for three separate cases:
378374

379375
- No argument defauls to the `charSet32` characters.
380376
- One of six predefined `CharSet`s can be specified.
381377
- A string representing the characters to use can be specified.
382378

383379
The last option above will throw an `EntropyStringError` if the characters string isn't appropriate for creating a `CharSet`.
384380
```js
385-
const {Random} = require('entropy-string')
381+
const {Entropy} = require('entropy-string')
386382

387383
try {
388-
const random = new Random('123456')
384+
const entropy = new Entropy('123456')
389385
}
390386
catch(error) {
391387
console.log('Error: ' + error.message)
@@ -396,7 +392,7 @@ The last option above will throw an `EntropyStringError` if the characters strin
396392
397393
```js
398394
try {
399-
const random = new Random('01233210')
395+
const entropy = new Entropy('01233210')
400396
}
401397
catch(error) {
402398
console.log(error.message)
@@ -430,20 +426,20 @@ There are two significant issues with this code. `Math.random` returns a random
430426
Compare that to the `entropy-string` scheme. For the example above, slicing off 5 bits at a time requires a total of 80 bits (10 bytes). Creating the same strings as above, `entropy-string` uses 80 bits of randomness per string with no wasted bits. In general, the `entropy-string` scheme can waste up to 7 bits per string, but that's the worst case scenario and that's *per string*, not *per character*!
431427

432428
```js
433-
const {Random} = require('entropy-string')
429+
const {Entropy} = require('entropy-string')
434430

435-
const random = new Random()
436-
let string = random.string(80)
431+
const entropy = new Entropy()
432+
let string = entropy.string(80)
437433
```
438434

439435
> HFtgHQ9q9fH6B8HM
440436
441437
But there is an even bigger issue with the previous code from a security perspective. `Math.random` *is not a cryptographically strong random number generator*. **_Do not_** use `Math.random` to create strings used for security purposes! This highlights an important point. Strings are only capable of carrying information (entropy); it's the random bytes that actually provide the entropy itself. `entropy-string` automatically generates the necessary bytes needed to create cryptographically strong random strings using the `crypto` library.
442438

443-
However, if you don't need cryptographically strong random strings, you can request `entropy-string` use `Math.random` rather than the `crypto` library by using `random.stringRandom`:
439+
However, if you don't need cryptographically strong random strings, you can request `entropy-string` use `Math.random` rather than the `crypto` library by using `entropy.stringRandom`:
444440

445441
```js
446-
string = random.stringRandom(80)
442+
string = entropy.stringRandom(80)
447443
```
448444

449445
> fdRp9Q3rTMF7TdFN
@@ -456,25 +452,25 @@ Fortunately you don't need to really understand how the bytes are efficiently sl
456452

457453
### <a name="CustomBytes"></a>Custom Bytes
458454

459-
As described in [Efficiency](#Efficiency), `entropy-string` automatically generates random bytes using the `crypto` library. But you may have a need to provide your own bytes, say for deterministic testing or to use a specialized byte generator. The `random.string` function allows passing in your own bytes to create a string.
455+
As described in [Efficiency](#Efficiency), `entropy-string` automatically generates random bytes using the `crypto` library. But you may have a need to provide your own bytes, say for deterministic testing or to use a specialized byte generator. The `entropy.string` function allows passing in your own bytes to create a string.
460456

461457
Suppose we want a string capable of 30 bits of entropy using 32 characters. We pass in 4 bytes to cover the 30 bits needed to generate six base 32 characters:
462458

463459
```js
464-
const {Random} = require('entropy-string')
460+
const {Entropy} = require('entropy-string')
465461

466-
const random = new Random()
462+
const entropy = new Entropy()
467463
const bytes = Buffer.from([250, 200, 150, 100])
468-
let string = random.stringWithBytes(30, bytes)
464+
let string = entropy.stringWithBytes(30, bytes)
469465
```
470466

471467
> Th7fjL
472468
473-
The __bytes__ provided can come from any source. However, the number of bytes must be sufficient to generate the string as described in the [Efficiency](#Efficiency) section. `random.stringWithBytes` throws an `Error` if the string cannot be formed from the passed bytes.
469+
The __bytes__ provided can come from any source. However, the number of bytes must be sufficient to generate the string as described in the [Efficiency](#Efficiency) section. `entropy.stringWithBytes` throws an `Error` if the string cannot be formed from the passed bytes.
474470

475471
```js
476472
try {
477-
string = random.stringWithBytes(32, bytes)
473+
string = entropy.stringWithBytes(32, bytes)
478474
}
479475
catch(error) {
480476
console.log(' Error: ' + error.message)
@@ -526,13 +522,13 @@ The final line represents the number of entropy bits `N` as a function of the nu
526522

527523
##### Base 32 character string with a 1 in a million chance of a repeat a billion strings:
528524
```js
529-
const {Random, Entropy} = require('entropy-string')
525+
const { Entropy } = require('entropy-string')
530526

531-
const random = new Random()
532527
const bits = Entropy.bits(1e6,1e9)
533-
const string = random.string(bits)
528+
const entropy = new Entropy()
529+
const string = entropy.string(bits)
534530
```
535531

536-
> DdHrT2NdrHf8tM
532+
> LtH4p6rnRHT2bb2rf3
537533
538534
[TOC](#TOC)

dist/lib/charSet.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
2020

2121
var WeakMap = require('weak-map');
2222

23-
var lcm = require('./lcm').default;
23+
var _require = require('./lcm'),
24+
lcm = _require.default;
2425

2526
var propMap = new WeakMap();
2627

0 commit comments

Comments
 (0)