flexi-human-hash 0.0.1 → 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020-2025 Adam Powers
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,45 +1,212 @@
1
- # flexi-human-hash
1
+ ## flexi-human-hash
2
+ There are lots of packages that convert big random numbers to something readable or create random strings from words, but none are as flexible as I wanted. I created this to be a highly controllable version of the other human hash packages.
3
+
4
+ Note that this package is well tested and fairly stable, so don't expect to see many changes unless new GitHub issues are opened.
5
+
6
+ ## Usage
7
+ Install:
8
+ ``` bash
9
+ npm install flexi-human-hash
10
+ ```
11
+
12
+ Use
13
+ ``` js
14
+ import { FlexiHumanHash } from "flexi-human-hash";
15
+ const fhh = new FlexiHumanHash("{{adjective}}-{{noun}}");
16
+ console.log(fhh.hash());
17
+ // Expected output: "betwixt-railways"
18
+ ```
19
+
20
+ ## Features:
21
+ * Multiple dictionaries: nouns, adjectives, verbs, first name, last name, city
22
+ * Full control over formatting: separators, spaces, additional words, upper case, lower case, numbers
23
+ * Random: You provide the source of randomness (hash, string, uuid, etc) or one will be provided for you
24
+ * Reversable hashes: hashes can be converted back to their random number
25
+ * Entropy reporting: understand how likely hash collisions are for your given format
26
+ * Low learning curve: good documentation and examples
27
+ * Extendable: add your own dictionaries and formatting transforms
28
+ * Dictionaries aren't loaded unless used, reduces bloat
29
+ * Command line: use the JavaScript API or use it from the command line!
30
+
31
+ ## API Examples:
32
+ Simple hash, you provide the random numbers
33
+ ``` js
34
+ const fhh = new FlexiHumanHash("{{adjective}}-{{adjective}}-{{noun}}-{{decimal 4}}");
35
+ fhh.hash("edf63145-f6d3-48bf-a0b7-18e2eeb0a9dd");
36
+ // Expected output: "disagreeably-thankless-newsgirls-3149"
37
+ ```
38
+
39
+ Another format, random number provided for you
40
+ ``` js
41
+ const fhh = new FlexiHumanHash("{{adjective}}, {{adjective}} {{noun}} {{hex 4}}");
42
+ fhh.hash();
43
+ // Expected output: "stalwart, dominant attire f214"
44
+ ```
45
+
46
+ Another format, md5 hash a string for random numbers, transform names to all caps
47
+ ``` js
48
+ const fhh = new FlexiHumanHash("{{first-name caps}}-{{last-name caps}}-{{decimal 6}}");
49
+ fhh.hash("this is my password...", {hashAlg: "md5"});
50
+ // Expected output: "CHARITY-ESMERELDA-903817"
51
+ ```
52
+
53
+ Reverse a string back to the original random number
54
+ ``` js
55
+ const fhh = new FlexiHumanHash("{{first-name lowercase}}-{{last-name lowercase}}-the-{{adjective}}-{{noun}}");
56
+ const ret = fhh.unhash("francisca-straub-the-coldest-eagle");
57
+ // Expected output: [57, 225, 104, 232, 109, 102, 74 ]
58
+ ```
59
+
60
+ Report how much entropy is used for a format to help understand likelihood of collisions
61
+ ``` js
62
+ const fhh = new FlexiHumanHash("{{first-name uppercase}}-{{last-name uppercase}}-{{decimal 6}}");
63
+ console.log(fhh.entropy);
64
+ // Expected output (note BigInt): "70368744177664n"
65
+ console.log("Number of combinations:", fhh.entropy.toLocaleString());
66
+ // Expected output: "Number of combinations: 70,368,744,177,664"
67
+ console.log(`Entropy: 2^${fhh.entropyBase2}`);
68
+ // Expected output: "Entropy: 2^46"
69
+ console.log(`Entropy: 10^${fhh.entropyBase10}`);
70
+ // Expected output: "Entropy: 10^14"
71
+ ```
72
+
73
+ Add a dictionary
74
+ ``` js
75
+ const scientificTerms = [
76
+ "antigens",
77
+ "magnetron",
78
+ "nanoarchitectonics",
79
+ "spintronics",
80
+ "teflon",
81
+ "transistor",
82
+ /* ... */
83
+ ];
84
+
85
+ function registerScientificTerms() {
86
+ return {
87
+ size: scientificTerms.length,
88
+ getEntry: function(n) {
89
+ return scientificTerms[n];
90
+ },
91
+ };
92
+ }
93
+
94
+ FlexiHumanHash.registerDictionary("science", registerScientificTerms);
95
+ const fhh = new FlexiHumanHash("{{adjective}}:{{science}}");
96
+ fhh.hash();
97
+ // Expected output: "archetypical:spintronics"
98
+ ```
99
+
100
+ Add a transform
101
+ ``` js
102
+ function reverseString(str) {
103
+ return str.split("").reverse().join("");
104
+ }
105
+
106
+ FlexiHumanHash.registerTransform("reverse", reverseString);
107
+ const fhh = new FlexiHumanHash("{{adjective reverse}}-{{noun reverse}}");
108
+ fhh.hash();
109
+ // Expected output: "ydeewt-airalos"
110
+ ```
111
+
112
+ <!--
113
+ ## Command Line Examples:
114
+ ``` bash
115
+ flexihash "{{first-name}}-{{last-name}}" f373c0aec6162cdba76ee9084e695866a15e441a
116
+ ```
117
+
118
+ ``` bash
119
+ flexihash "{{first-name}}-{{last-name}}" < file
120
+ ```
121
+ -->
122
+
123
+ ## Formats
124
+ * noun
125
+ * 47,004 English nouns from [categorized-words](https://github.com/felixfischer/categorized-words)
126
+ * verb
127
+ * 31,232 English verbs from [categorized-words](https://github.com/felixfischer/categorized-words)
128
+ * adjective
129
+ * 14,903 English adjectives from [categorized-words](https://github.com/felixfischer/categorized-words)
130
+ * decimal
131
+ * A decimal number (zero through 10), defaults to four digits long but can be a specified number of digits long
132
+ * {{decimal}} = 2394
133
+ * {{decimal 8}} = 84258973
134
+ * {{decimal 1}} = 7
135
+ * hex
136
+ * A hexidecimal number (zero through f), defaults to four nibbles / characters long but can be a specified number of digits long
137
+ * {{hex}} = 3fa8
138
+ * {{hex 8}} = cb28f30d
139
+ * {{hex 1}} = e
140
+ * female-name
141
+ * 4,951 English capitalized female first names / given names from [@stdlib](https://github.com/stdlib-js/datasets-female-first-names-en)
142
+ * male-name
143
+ * 3,898 English capitalized male first names / given names from [@stdlib](https://github.com/stdlib-js/datasets-male-first-names-en)
144
+ * first-name
145
+ * 8,849 English capitalized first names / given names (female-name and male-name combined)
146
+ * last-name
147
+ * 21,985 last names / family names from [uuid-readable](https://github.com/Debdut/uuid-readable)
148
+ * city
149
+ * 138,398 city names from [all-the-cities](https://www.npmjs.com/package/all-the-cities)
150
+
151
+ ## Transforms
152
+ Note: transforms with "=" in them must come last, because [Handlebars](https://handlebarsjs.com/). e.g. "{{noun uppercase max-length=4}}" works, but "{{noun max-length=4 uppercase}}" will throw a parsing error.
153
+
154
+ * uppercase
155
+ * Converts the first letter of a word to uppercase
156
+ * e.g. "{{noun uppercase}}" -> "Word"
157
+ * lowercase
158
+ * Converts an entire word to lowercase
159
+ * e.g. "{{noun lowercase}}" -> "word"
160
+ * caps
161
+ * Converts an entire word to uppercase
162
+ * e.g. "{{noun caps}}" -> "WORD"
163
+ * max-length=n
164
+ * Filters a dictionary to only include words 'n' letters long or less
165
+ * e.g. "{{noun max-length=4}}" => "cat" or "blob" (not "building")
166
+ * min-length=n
167
+ * Filters a dictionary to only include words 'n' letters long or more
168
+ * e.g. "{{noun min-length=5}}" => "cloud" or "building" (not "cat")
169
+ * exact-length=n
170
+ * Filters a dictionary to only include words 'n' letters long or less
171
+ * e.g. "{{noun exact-length=4}}" => "tree" or "bush" (not "cat", not "building")
172
+
173
+ ## API
174
+ * FlexiHumanHash
175
+ * Class, constructor takes a `format` string and an options object
176
+ * e.g. `new FlexiHumanHash(formatString)`
177
+ * `hash(randomness, options)`: uses randomness to create a string in the specified format
178
+ * `randomness` can be a: string, array of numbers, iterable of numbers, TypedArray, ArrayBuffer
179
+ * options:
180
+ * hashAlg: a string passed to [Node Crypto createHash](https://nodejs.org/api/crypto.html#class-hash). The algorithm must be acceptable by the local installation of OpenSSL ("sha256" is a good guess if you don't know better). If used, `randomness` must be an argument acceptable to Node Crypto's hash `.update()` function.
181
+ * hashSalt: Used in combination with `hashAlg` -- is passed to the `.update()` method before `randomness` to create a different output hash. Must be an argument acceptable to Node Crypto's hash `.update()` function.
182
+ * FlexiHumanHash.registerDictionary(name, registerFn)
183
+ * `name` of the dictionary that will be used in the format
184
+ * e.g. `name` = "foo" becomes "{{foo}}"
185
+ * `registerFn` returns an object with:
186
+ * size: number of entries in the dictionary
187
+ * getEntry: function with one arg (n), that returns the Nth entry of the dictionary
188
+ * FlexiHumanHash.registerTransform(name, transformFn, reverseFn)
189
+ * `name` of the transform that will be used in the format
190
+ * e.g. `name` = "bar" becomes "{{noun bar}}"
191
+ * `transformFn` is a function with one argument, the word that will be transformed. Returns the transformed word.
192
+ * `reverseFn` TODO
193
+
194
+ ## Similar packages
195
+ * [Project Name Generator](https://www.npmjs.com/package/project-name-generator)
196
+ * [Codenamize JS](https://github.com/stemail23/codenamize-js)
197
+ * [UUID Readable](https://www.npmjs.com/package/uuid-readable)
198
+ * [GUID in Words](https://www.npmjs.com/package/guid-in-words)
199
+ * [Mnemonic ID](https://www.npmjs.com/package/mnemonic-id)
200
+ * [Human Readable IDs](https://www.npmjs.com/package/human-readable-ids)
201
+ * [Wordhash](https://www.npmjs.com/package/wordhash)
202
+ * [Human Readable](https://www.npmjs.com/package/@jekru/human-readable)
203
+ * [Humanize Digest](https://www.npmjs.com/package/humanize-digest)
204
+ * [UUID API Key](https://www.npmjs.com/package/uuid-apikey)
205
+
206
+ ## Future ambitions
207
+ * Add more dictionaries!
208
+ * Add [Chroma Hash](https://github.com/mattt/Chroma-Hash) and other non-word hashes
209
+
210
+ Issues and pull requests always welcome, even if you're just saying hi. :)
2
211
 
3
- ## ⚠️ IMPORTANT NOTICE ⚠️
4
212
 
5
- **This package is created solely for the purpose of setting up OIDC (OpenID Connect) trusted publishing with npm.**
6
-
7
- This is **NOT** a functional package and contains **NO** code or functionality beyond the OIDC setup configuration.
8
-
9
- ## Purpose
10
-
11
- This package exists to:
12
- 1. Configure OIDC trusted publishing for the package name `flexi-human-hash`
13
- 2. Enable secure, token-less publishing from CI/CD workflows
14
- 3. Establish provenance for packages published under this name
15
-
16
- ## What is OIDC Trusted Publishing?
17
-
18
- OIDC trusted publishing allows package maintainers to publish packages directly from their CI/CD workflows without needing to manage npm access tokens. Instead, it uses OpenID Connect to establish trust between the CI/CD provider (like GitHub Actions) and npm.
19
-
20
- ## Setup Instructions
21
-
22
- To properly configure OIDC trusted publishing for this package:
23
-
24
- 1. Go to [npmjs.com](https://www.npmjs.com/) and navigate to your package settings
25
- 2. Configure the trusted publisher (e.g., GitHub Actions)
26
- 3. Specify the repository and workflow that should be allowed to publish
27
- 4. Use the configured workflow to publish your actual package
28
-
29
- ## DO NOT USE THIS PACKAGE
30
-
31
- This package is a placeholder for OIDC configuration only. It:
32
- - Contains no executable code
33
- - Provides no functionality
34
- - Should not be installed as a dependency
35
- - Exists only for administrative purposes
36
-
37
- ## More Information
38
-
39
- For more details about npm's trusted publishing feature, see:
40
- - [npm Trusted Publishing Documentation](https://docs.npmjs.com/generating-provenance-statements)
41
- - [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
42
-
43
- ---
44
-
45
- **Maintained for OIDC setup purposes only**
package/data/README.md ADDED
@@ -0,0 +1 @@
1
+ last.json is borrowed from https://github.com/Debdut/uuid-readable. thanks!