pts 0.12.8 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/uheprng.ts ADDED
@@ -0,0 +1,153 @@
1
+ /* This code has been written by Steve Gibson and can be found here:
2
+ *
3
+ * https://www.grc.com/otg/uheprng.htm
4
+ *
5
+ * The code has been converted to typescript and unused functions have
6
+ * been removed.
7
+ *
8
+ * Port notes:
9
+ * - Only the seeded, deterministic path survives: the original's
10
+ * nondeterministic startup fill (from the host's `Math.random`) fed a
11
+ * usage this port removed, so it is omitted and seeding consumes no
12
+ * outside entropy.
13
+ * - `random()` returns the raw 32-bit MWC fraction — every draw is an
14
+ * exact multiple of 2^-32. The original composed two draws into a
15
+ * 53-bit double; callers here (Float32-based Pts) don't need that.
16
+ * - Despite the original header below, this is not a cryptographically
17
+ * secure PRNG by modern standards (its state is recoverable from its
18
+ * outputs). Pts uses it for reproducible generative art only.
19
+ */
20
+
21
+ /* ============================================================================
22
+ Gibson Research Corporation
23
+ UHEPRNG - Ultra High Entropy Pseudo-Random Number Generator
24
+ ============================================================================
25
+ LICENSE AND COPYRIGHT: THIS CODE IS HEREBY RELEASED INTO THE PUBLIC DOMAIN
26
+ Gibson Research Corporation releases and disclaims ALL RIGHTS AND TITLE IN
27
+ THIS CODE OR ANY DERIVATIVES. Anyone may be freely use it for any purpose.
28
+ ============================================================================
29
+ This is GRC's cryptographically strong PRNG (pseudo-random number generator)
30
+ for JavaScript. It is driven by 1536 bits of entropy, stored in an array of
31
+ 48, 32-bit JavaScript variables. Since many applications of this generator,
32
+ including ours with the "Off The Grid" Latin Square generator, may require
33
+ the deteriministic re-generation of a sequence of PRNs, this PRNG's initial
34
+ entropic state can be read and written as a static whole, and incrementally
35
+ evolved by pouring new source entropy into the generator's internal state.
36
+ ----------------------------------------------------------------------------
37
+ ENDLESS THANKS are due Johannes Baagoe for his careful development of highly
38
+ robust JavaScript implementations of JS PRNGs. This work was based upon his
39
+ JavaScript "Alea" PRNG which is based upon the extremely robust Multiply-
40
+ With-Carry (MWC) PRNG invented by George Marsaglia. MWC Algorithm References:
41
+ http://www.GRC.com/otg/Marsaglia_PRNGs.pdf
42
+ http://www.GRC.com/otg/Marsaglia_MWC_Generators.pdf
43
+ ----------------------------------------------------------------------------
44
+ The quality of this algorithm's pseudo-random numbers have been verified by
45
+ multiple independent researchers. It handily passes the fermilab.ch tests as
46
+ well as the "diehard" and "dieharder" test suites. For individuals wishing
47
+ to further verify the quality of this algorithm's pseudo-random numbers, a
48
+ 256-megabyte file of this algorithm's output may be downloaded from GRC.com,
49
+ and a Microsoft Windows scripting host (WSH) version of this algorithm may be
50
+ downloaded and run from the Windows command prompt to generate unique files
51
+ of any size:
52
+ The Fermilab "ENT" tests: http://fourmilab.ch/random/
53
+ The 256-megabyte sample PRN file at GRC: https://www.GRC.com/otg/uheprng.bin
54
+ The Windows scripting host version: https://www.GRC.com/otg/wsh-uheprng.js
55
+ ----------------------------------------------------------------------------
56
+ Qualifying MWC multipliers are: 187884, 686118, 898134, 1104375, 1250205,
57
+ 1460910 and 1768863. (We use the largest one that's < 2^21)
58
+ ============================================================================
59
+ */
60
+
61
+ /* ============================================================================
62
+ This is based upon Johannes Baagoe's carefully designed and efficient hash
63
+ function for use with JavaScript. It has a proven "avalanche" effect such
64
+ that every bit of the input affects every bit of the output 50% of the time,
65
+ which is good. See: http://baagoe.com/en/RandomMusings/hash/avalanche.xhtml
66
+ ============================================================================
67
+ */
68
+ // calling with no (or a falsy) argument resets the hash state instead of
69
+ // hashing — initState and the empty-seed path rely on that contract (the
70
+ // reset path's return value is never consumed)
71
+ function Mash(): (data?: string) => number {
72
+ let n = 0xefc8249d;
73
+ return function (data?: string): number {
74
+ if (data) {
75
+ data = data.toString();
76
+ for (let i = 0; i < data.length; i++) {
77
+ n += data.charCodeAt(i);
78
+ let h = 0.02519603282416938 * n;
79
+ n = h >>> 0;
80
+ h -= n;
81
+ h *= n;
82
+ n = h >>> 0;
83
+ h -= n;
84
+ n += h * 0x100000000; // 2^32
85
+ }
86
+ return (n >>> 0) * 2.3283064365386963e-10; // 2^-32
87
+ }
88
+ n = 0xefc8249d;
89
+ return 0;
90
+ };
91
+ }
92
+
93
+ export default function uheprng(seed: string) {
94
+ const o = 48; // set the 'order' number of ENTROPY-holding 32-bit values
95
+ let c = 1; // init the 'carry' used by the multiply-with-carry (MWC) algorithm
96
+ let p = o; // init the 'phase' (max-1) of the intermediate variable pointer
97
+ const s: number[] = new Array(o); // declare our intermediate variables array
98
+
99
+ const mash = Mash(); // get a pointer to our high-performance "Mash" hash
100
+
101
+ // initialize the mash hash and the PRNG's internal state to a fixed,
102
+ // deterministic startup context before hashing in the seeding input
103
+ function initState() {
104
+ mash(); // pass a null arg to force mash hash to init
105
+ for (let i = 0; i < o; i++) s[i] = mash(" "); // fill the array with initial mash hash values
106
+ c = 1; // init our multiply-with-carry carry
107
+ p = o; // init our phase
108
+ }
109
+
110
+ // this "clean string" function removes leading and trailing spaces and non-printing
111
+ // control characters, including any embedded carriage-return (CR) and line-feed (LF)
112
+ // characters, from any string it is handed. this is used by the 'hashString' function
113
+ // (below) so users always obtain the same EFFECTIVE uheprng seeding key: seeds that
114
+ // differ only by surrounding whitespace or embedded control characters collide.
115
+ function cleanString(inStr: string): string {
116
+ inStr = inStr.replace(/(^\s*)|(\s*$)/gi, ""); // remove any/all leading spaces
117
+ inStr = inStr.replace(/[\x00-\x1F]/gi, ""); // remove any/all control characters
118
+ return inStr; // return the cleaned up result
119
+ }
120
+
121
+ // this "hash string" function hashes the provided character string after first cleaning
122
+ // it (above); an empty effective seed leaves the fixed initState context untouched
123
+ function hashString(inStr: string) {
124
+ inStr = cleanString(inStr);
125
+ mash(inStr); // use the string to evolve the 'mash' state
126
+ for (let i = 0; i < inStr.length; i++) {
127
+ // scan through the characters in our string
128
+ const k = inStr.charCodeAt(i).toString(); // stringify once per character, not per slot
129
+ for (let j = 0; j < o; j++) {
130
+ // "mash" it into the UHEPRNG state
131
+ s[j] -= mash(k);
132
+ if (s[j] < 0) s[j] += 1;
133
+ }
134
+ }
135
+ }
136
+
137
+ initState();
138
+ hashString(seed);
139
+
140
+ return {
141
+ /**
142
+ * this (not anymore) PRIVATE (internal access only) function is the heart of the multiply-with-carry
143
+ * (MWC) PRNG algorithm. When called it returns a pseudo-random number in the form of a
144
+ * 32-bit JavaScript fraction (0.0 to <1.0) — an exact multiple of 2^-32.
145
+ * @returns a number between 0.0 and 1.0
146
+ */
147
+ random(): number {
148
+ if (++p >= o) p = 0;
149
+ const t = 1768863 * s[p] + c * 2.3283064365386963e-10; // 2^-32
150
+ return (s[p] = t - (c = t | 0));
151
+ },
152
+ };
153
+ }