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 +21 -0
- package/README.md +210 -43
- package/data/README.md +1 -0
- package/data/last.json +21988 -0
- package/index.js +18 -0
- package/lib/FlexiArrayDict.js +126 -0
- package/lib/FlexiDict.js +42 -0
- package/lib/FlexiHumanHash.js +325 -0
- package/lib/RandomSource.js +108 -0
- package/lib/defaultDicts.js +102 -0
- package/lib/defaultTransforms.js +17 -0
- package/package.json +126 -5
- package/types/index.d.ts +171 -0
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
|
-
|
|
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!
|