You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+23-11Lines changed: 23 additions & 11 deletions
Original file line number
Diff line number
Diff line change
@@ -96,9 +96,16 @@ The [Swift Package Manager](https://swift.org/package-manager/) is a decentraliz
96
96
97
97
[TOC](#TOC)
98
98
99
+
----
100
+
101
+
The remainer of this README is included in the project as a Swift playground for interactive exploration.
102
+
103
+
----
104
+
105
+
99
106
## <a name="BasicUsage"></a>Basic Usage
100
107
101
-
Calculate *bits* of entropy to cover **1 million strings** with a repeat *risk* of **1 in a billion** and generate a *string* using a set of **32 characters**:
108
+
Calculate the bits of entropy necessary to cover a *risk* of a **1 in a billion** chance of a repeat in a *total* of **1 million** strings and generate a example string using a set of 32 characters:
102
109
103
110
```swift
104
111
import EntropyString
@@ -109,7 +116,7 @@ Calculate *bits* of entropy to cover **1 million strings** with a repeat *risk*
109
116
110
117
> 9Pp7MDDm7b9Dhb
111
118
112
-
Generate a *string* of the same *entropy* using a set of **16 characters** (hexadecimal):
119
+
Generate a string of the same entropy using a set of 16 characters (hexadecimal):
@@ -135,20 +142,19 @@ We'll begin investigating `EntropyString` by considering our [Real Need](Read%20
135
142
136
143
## <aname="RealNeed"></a>Real Need
137
144
138
-
Let's start by reflecting on a common statement of need of developers, who might say:
145
+
Let's start by reflecting on a common statement of need for developers, who might say:
139
146
140
147
*I need random strings 16 characters long.*
141
148
142
-
Okay. There are libraries available that address that exact need. But first, there are some
143
-
questions that arise from the need as stated, such as:
149
+
Okay. There are libraries available that address that exact need. But first, there are some questions that arise from the need as stated, such as:
144
150
145
151
1. What characters do you want to use?
146
152
2. How many of these strings do you need?
147
153
3. Why do you need these strings?
148
154
149
155
The available libraries often let you specify the characters to use. So we can assume for now that question 1 is answered with:
150
156
151
-
*Hexadecimal IDs will do fine*.
157
+
*Hexadecimal will do fine*.
152
158
153
159
As for question 2, the developer might respond:
154
160
@@ -168,13 +174,15 @@ Probabilistic uniqueness contains risk. That's the price we pay for giving up on
168
174
169
175
*I guess I can live with a 1 in a million chance of a repeat*.
170
176
171
-
So now we've gotten to the real need:
177
+
So now we've gotten to the developer's real need:
172
178
173
179
*I need 10,000 random hexadecimal IDs with less than 1 in a million chance of any repeats*.
174
180
175
-
How do you address this need using a library designed to generate strings of specified length? Well, you don't directly, because that library was designed to answer the originally stated need, not the real need we've uncovered. We need a library that deals with probabilistic uniqueness of a total number of some strings. And that's exactly what `EntropyString` does.
181
+
Not only is this statement more specific, note there is no mention of string length. The developer needs probabilistic uniqueness, and strings are to be used to capture randomness for this purpose. As such, the length of the string is simply a by-product of the encoding used to represent the required uniqueness as a string.
176
182
177
-
Let's use `EntropyString` to help this developer:
183
+
So how do you address this need using a library designed to generate strings of specified length? Well, you don't directly, because that library was designed to answer the originally stated need, not the real need we've uncovered. We need a library that deals with probabilistic uniqueness of a total number of some strings. And that's exactly what `EntropyString` does.
184
+
185
+
Let's use `EntropyString` to help this developer by generating 5 IDs:
178
186
179
187
```swift
180
188
importEntropyString
@@ -196,13 +204,13 @@ To generate the IDs, we first use
196
204
let bits = Entropy.bits(total: 10000, risk: .ten06)
197
205
```
198
206
199
-
to determine the bits of entropy needed to satisfy our probabilistic uniqueness of **10,000** strings with a **1 in a million** (ten to the sixth power) risk of repeat. We didn't print the result, but if you did you'd see it's about **45.51**. Then inside a loop we used
207
+
to determine how much entropy is needed to satisfy the probabilistic uniqueness of a **1 in a million** (ten to the sixth power) risk of repeat in a total of **10,000** strings. We didn't print the result, but if you did you'd see it's about **45.51** bits. Then inside a loop we used
200
208
201
209
```swift
202
210
let string = RandomString.entropy(of: bits, using: .charSet16)
203
211
```
204
212
205
-
to actually generate random strings using hexadecimal (charSet16) characters. Looking at the IDs, we can see each is 12 characters long. Again, the string length is a by-product of the characters used to represent the entropy we needed. And it seems the developer didn't really need 16 characters after all.
213
+
to actually generate a random string of the specified entropy using hexadecimal (charSet16) characters. Looking at the IDs, we can see each is 12 characters long. Again, the string length is a by-product of the characters used to represent the entropy we needed. And it seems the developer didn't really need 16 characters after all.
206
214
207
215
Finally, given that the strings are 12 hexadecimals long, each string actually has an information carrying capacity of 12 * 4 = 48 bits of entropy (a hexadecimal character carries 4 bits). That's fine. Assuming all characters are equally probable, a string can only carry entropy equal to a multiple of the amount of entropy represented per character. `EntropyString` produces the smallest strings that *exceed* the specified entropy.
208
216
@@ -477,6 +485,8 @@ Rather than have `EntropyString` generate bytes automatically, you can provide y
477
485
478
486
As described in [Secure Bytes](#SecureBytes), `EntropyString` automatically generates random bytes using either `SecRandomCopyBuf` or `arc4random_buf`. These functions are fine, but you may have a need to provide your own btyes, say for deterministic testing or to use a specialized byte genterator. The `RandomString.entropy(of:using:bytes)` function allows passing in your own bytes to create a string.
479
487
488
+
Suppose we want a string capable of 30 bits of entropy using 32 characters. We pass in 4 bytes (to cover the 30 bits):
489
+
480
490
```swift
481
491
importEntropyString
482
492
@@ -500,4 +510,6 @@ The __bytes__ provided can come from any source. However, the number of bytes mu
500
510
501
511
> error: tooFewBytes
502
512
513
+
Note how the number of bytes needed is dependent on the number of characters in our set. In using a string to represent entropy, we can only generate entropy in multiples of the bits of entropy per character used. So in the example above, to get at least 32 bits of entropy using a character set of 32 characters (5 bits per char), we'll need enough bytes to cover 35 bits, not 32, so a `tooFewBytes` error is thrown.
0 commit comments