@aidc-toolkit/utility 1.0.24-beta → 1.0.26-beta
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/dist/character-set.d.ts +308 -0
- package/dist/character-set.d.ts.map +1 -0
- package/dist/character-set.js +564 -0
- package/dist/character-set.js.map +1 -0
- package/dist/exclusion.d.ts +26 -0
- package/dist/exclusion.d.ts.map +1 -0
- package/dist/exclusion.js +18 -0
- package/dist/exclusion.js.map +1 -0
- package/dist/index.d.ts +26 -947
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -3504
- package/dist/index.js.map +1 -1
- package/dist/iterable-utility.d.ts +39 -0
- package/dist/iterable-utility.d.ts.map +1 -0
- package/dist/iterable-utility.js +35 -0
- package/dist/iterable-utility.js.map +1 -0
- package/dist/locale/en/locale-resources.d.ts +33 -0
- package/dist/locale/en/locale-resources.d.ts.map +1 -0
- package/dist/locale/en/locale-resources.js +32 -0
- package/dist/locale/en/locale-resources.js.map +1 -0
- package/dist/locale/fr/locale-resources.d.ts +33 -0
- package/dist/locale/fr/locale-resources.d.ts.map +1 -0
- package/dist/locale/fr/locale-resources.js +32 -0
- package/dist/locale/fr/locale-resources.js.map +1 -0
- package/dist/locale/i18n.d.ts +27 -0
- package/dist/locale/i18n.d.ts.map +1 -0
- package/dist/locale/i18n.js +34 -0
- package/dist/locale/i18n.js.map +1 -0
- package/dist/record.d.ts +44 -0
- package/dist/record.d.ts.map +1 -0
- package/dist/record.js +58 -0
- package/dist/record.js.map +1 -0
- package/dist/reg-exp.d.ts +43 -0
- package/dist/reg-exp.d.ts.map +1 -0
- package/dist/reg-exp.js +55 -0
- package/dist/reg-exp.js.map +1 -0
- package/dist/sequence.d.ts +68 -0
- package/dist/sequence.d.ts.map +1 -0
- package/dist/sequence.js +96 -0
- package/dist/sequence.js.map +1 -0
- package/dist/string.d.ts +25 -0
- package/dist/string.d.ts.map +1 -0
- package/dist/string.js +2 -0
- package/dist/string.js.map +1 -0
- package/dist/transformer.d.ts +347 -0
- package/dist/transformer.d.ts.map +1 -0
- package/dist/transformer.js +457 -0
- package/dist/transformer.js.map +1 -0
- package/package.json +11 -7
- package/src/character-set.ts +20 -19
- package/src/exclusion.ts +6 -1
- package/src/index.ts +9 -9
- package/src/locale/i18n.ts +3 -3
- package/src/locale/i18next.d.ts +1 -1
- package/src/record.ts +2 -2
- package/src/reg-exp.ts +7 -7
- package/src/string.ts +3 -3
- package/src/transformer.ts +19 -18
- package/test/character-set.test.ts +1 -1
- package/test/record.test.ts +4 -2
- package/test/reg-exp.test.ts +1 -1
- package/test/sequence.test.ts +1 -1
- package/test/setup.ts +1 -1
- package/test/transformer.test.ts +1 -1
- package/tsconfig-config.json +4 -0
- package/tsconfig-src.json +8 -0
- package/tsconfig-test.json +9 -0
- package/tsconfig.json +12 -1
- package/tsup.config.ts +3 -2
- package/dist/index.cjs +0 -3569
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -947
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
import { mapIterable } from "./iterable-utility.js";
|
|
2
|
+
import { i18nextUtility } from "./locale/i18n.js";
|
|
3
|
+
import { Sequence } from "./sequence.js";
|
|
4
|
+
/**
|
|
5
|
+
* Transformer that transforms values in a numeric domain to values in a range equal to the domain or to another range
|
|
6
|
+
* defined by a callback function. In other words, the domain determines valid input values and, without a callback, the
|
|
7
|
+
* range of valid output values.
|
|
8
|
+
*
|
|
9
|
+
* The concept is similar to {@link https://en.wikipedia.org/wiki/Format-preserving_encryption | format-preserving
|
|
10
|
+
* encryption}, where input values within a specified domain (e.g., {@link
|
|
11
|
+
* https://en.wikipedia.org/wiki/Payment_card_number | payment card numbers} ranging from 8-19 digits) are transformed
|
|
12
|
+
* into values in the same domain, typically for storage in a database where the data type and length are already fixed
|
|
13
|
+
* and exfiltration of the data can have significant repercussions.
|
|
14
|
+
*
|
|
15
|
+
* Two subclasses are supported directly by this class: {@linkcode IdentityTransformer} (which operates based on a
|
|
16
|
+
* domain only) and {@linkcode EncryptionTransformer} (which operates based on a domain and a tweak). If an application
|
|
17
|
+
* is expected to make repeated use of a transformer with the same domain and (optional) tweak and can't manage the
|
|
18
|
+
* transformer object, an in-memory cache is available via the {@linkcode get | get()} method. Properties in {@linkcode
|
|
19
|
+
* IdentityTransformer} and {@linkcode EncryptionTransformer} are read-only once constructed, so there is no issue with
|
|
20
|
+
* their shared use.
|
|
21
|
+
*/
|
|
22
|
+
export class Transformer {
|
|
23
|
+
/**
|
|
24
|
+
* Transformers cache, mapping a domain to another map, which maps an optional tweak to a transformer.
|
|
25
|
+
*/
|
|
26
|
+
static TRANSFORMER_MAPS_MAP = new Map();
|
|
27
|
+
/**
|
|
28
|
+
* Domain.
|
|
29
|
+
*/
|
|
30
|
+
_domain;
|
|
31
|
+
/**
|
|
32
|
+
* Constructor.
|
|
33
|
+
*
|
|
34
|
+
* @param domain
|
|
35
|
+
* Domain.
|
|
36
|
+
*/
|
|
37
|
+
constructor(domain) {
|
|
38
|
+
this._domain = BigInt(domain);
|
|
39
|
+
if (this._domain <= 0n) {
|
|
40
|
+
throw new RangeError(i18nextUtility.t("Transformer.domainMustBeGreaterThanZero", {
|
|
41
|
+
domain
|
|
42
|
+
}));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get a transformer, constructing it if necessary. The type returned is {@linkcode IdentityTransformer} if tweak is
|
|
47
|
+
* undefined, {@linkcode EncryptionTransformer} if tweak is defined. Note that although an {@linkcode
|
|
48
|
+
* EncryptionTransformer} with a zero tweak operates as an {@linkcode IdentityTransformer}, {@linkcode
|
|
49
|
+
* EncryptionTransformer} is still the type returned if a zero tweak is explicitly specified.
|
|
50
|
+
*
|
|
51
|
+
* @param domain
|
|
52
|
+
* Domain.
|
|
53
|
+
*
|
|
54
|
+
* @param tweak
|
|
55
|
+
* Tweak.
|
|
56
|
+
*
|
|
57
|
+
* @returns
|
|
58
|
+
* {@linkcode IdentityTransformer} if tweak is undefined, {@linkcode EncryptionTransformer} if tweak is defined.
|
|
59
|
+
*/
|
|
60
|
+
static get(domain, tweak) {
|
|
61
|
+
const domainN = BigInt(domain);
|
|
62
|
+
let transformersMap = Transformer.TRANSFORMER_MAPS_MAP.get(domainN);
|
|
63
|
+
if (transformersMap === undefined) {
|
|
64
|
+
transformersMap = new Map();
|
|
65
|
+
Transformer.TRANSFORMER_MAPS_MAP.set(domainN, transformersMap);
|
|
66
|
+
}
|
|
67
|
+
const tweakN = tweak === undefined ? undefined : BigInt(tweak);
|
|
68
|
+
let transformer = transformersMap.get(tweakN);
|
|
69
|
+
if (transformer === undefined) {
|
|
70
|
+
transformer = tweakN === undefined ? new IdentityTransformer(domainN) : new EncryptionTransformer(domainN, tweakN);
|
|
71
|
+
transformersMap.set(tweakN, transformer);
|
|
72
|
+
}
|
|
73
|
+
return transformer;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Get the domain.
|
|
77
|
+
*/
|
|
78
|
+
get domain() {
|
|
79
|
+
return this._domain;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Validate that a value is within the domain.
|
|
83
|
+
*
|
|
84
|
+
* @param value
|
|
85
|
+
* Value.
|
|
86
|
+
*/
|
|
87
|
+
validate(value) {
|
|
88
|
+
if (value < 0n) {
|
|
89
|
+
throw new RangeError(i18nextUtility.t("Transformer.valueMustBeGreaterThanOrEqualToZero", {
|
|
90
|
+
value
|
|
91
|
+
}));
|
|
92
|
+
}
|
|
93
|
+
if (value >= this.domain) {
|
|
94
|
+
throw new RangeError(i18nextUtility.t("Transformer.valueMustBeLessThan", {
|
|
95
|
+
value,
|
|
96
|
+
domain: this.domain
|
|
97
|
+
}));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Validate that a value is within the domain and do the work of transforming it forward.
|
|
102
|
+
*
|
|
103
|
+
* @param value
|
|
104
|
+
* Value.
|
|
105
|
+
*
|
|
106
|
+
* @returns
|
|
107
|
+
* Transformed value.
|
|
108
|
+
*/
|
|
109
|
+
validateDoForward(value) {
|
|
110
|
+
const valueN = BigInt(value);
|
|
111
|
+
this.validate(valueN);
|
|
112
|
+
return this.doForward(valueN);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Validate that a value is within the domain, do the work of transforming it forward, and apply a callback.
|
|
116
|
+
*
|
|
117
|
+
* @param transformerCallback
|
|
118
|
+
* Called after each value is transformed to convert it to its final value.
|
|
119
|
+
*
|
|
120
|
+
* @param value
|
|
121
|
+
* Value.
|
|
122
|
+
*
|
|
123
|
+
* @param index
|
|
124
|
+
* Index in sequence (0 for single transformation).
|
|
125
|
+
*
|
|
126
|
+
* @returns
|
|
127
|
+
* Transformed value.
|
|
128
|
+
*/
|
|
129
|
+
validateDoForwardCallback(transformerCallback, value, index) {
|
|
130
|
+
return transformerCallback(this.validateDoForward(value), index);
|
|
131
|
+
}
|
|
132
|
+
;
|
|
133
|
+
// eslint-disable-next-line jsdoc/require-jsdoc -- Implementation of overloaded signatures.
|
|
134
|
+
forward(valueOrValues, transformerCallback) {
|
|
135
|
+
// TODO Refactor type when https://github.com/microsoft/TypeScript/pull/56941 released.
|
|
136
|
+
let result;
|
|
137
|
+
if (typeof valueOrValues !== "object") {
|
|
138
|
+
result = transformerCallback === undefined ? this.validateDoForward(valueOrValues) : this.validateDoForwardCallback(transformerCallback, valueOrValues);
|
|
139
|
+
}
|
|
140
|
+
else if (valueOrValues instanceof Sequence) {
|
|
141
|
+
if (valueOrValues.minimumValue < 0n) {
|
|
142
|
+
throw new RangeError(i18nextUtility.t("Transformer.minimumValueMustBeGreaterThanOrEqualToZero", {
|
|
143
|
+
minimumValue: valueOrValues.minimumValue
|
|
144
|
+
}));
|
|
145
|
+
}
|
|
146
|
+
if (valueOrValues.maximumValue >= this.domain) {
|
|
147
|
+
throw new RangeError(i18nextUtility.t("Transformer.maximumValueMustBeLessThan", {
|
|
148
|
+
maximumValue: valueOrValues.maximumValue,
|
|
149
|
+
domain: this.domain
|
|
150
|
+
}));
|
|
151
|
+
}
|
|
152
|
+
result = transformerCallback === undefined ? mapIterable(valueOrValues, value => this.doForward(value)) : mapIterable(valueOrValues, (value, index) => transformerCallback(this.doForward(value), index));
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
result = transformerCallback === undefined ? mapIterable(valueOrValues, value => this.validateDoForward(value)) : mapIterable(valueOrValues, (value, index) => this.validateDoForwardCallback(transformerCallback, value, index));
|
|
156
|
+
}
|
|
157
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Type determination is handled above.
|
|
158
|
+
return result;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Transform a value in reverse.
|
|
162
|
+
*
|
|
163
|
+
* @param transformedValue
|
|
164
|
+
* Transformed value.
|
|
165
|
+
*
|
|
166
|
+
* @returns
|
|
167
|
+
* Value.
|
|
168
|
+
*/
|
|
169
|
+
reverse(transformedValue) {
|
|
170
|
+
const transformedValueN = BigInt(transformedValue);
|
|
171
|
+
this.validate(transformedValueN);
|
|
172
|
+
return this.doReverse(transformedValueN);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Identity transformer. Values are transformed to themselves.
|
|
177
|
+
*/
|
|
178
|
+
export class IdentityTransformer extends Transformer {
|
|
179
|
+
/**
|
|
180
|
+
* @inheritDoc
|
|
181
|
+
*/
|
|
182
|
+
doForward(value) {
|
|
183
|
+
return value;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* @inheritDoc
|
|
187
|
+
*/
|
|
188
|
+
doReverse(transformedValue) {
|
|
189
|
+
return transformedValue;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Encryption transformer. Values are transformed using repeated shuffle and xor operations, similar to those found in
|
|
194
|
+
* many cryptography algorithms, particularly AES. While sufficient for obfuscation of numeric sequences (e.g., serial
|
|
195
|
+
* number generation, below), if true format-preserving encryption is required, a more robust algorithm such as {@link
|
|
196
|
+
* https://doi.org/10.6028/NIST.SP.800-38Gr1.2pd | FF1} is recommended. Furthermore, no work has been done to mitigate
|
|
197
|
+
* {@link https://timing.attacks.cr.yp.to/index.html | timing attacks} for key detection.
|
|
198
|
+
*
|
|
199
|
+
* The purpose of the encryption transformer is to generate pseudo-random values in a deterministic manner to obscure
|
|
200
|
+
* the sequence of values generated over time. A typical example is for serial number generation, where knowledge of the
|
|
201
|
+
* sequence can infer production volumes (e.g., serial number 1000 implies that at least 1,000 units have been
|
|
202
|
+
* manufactured) or can be used in counterfeiting (e.g., a counterfeiter can generate serial numbers 1001, 1002, ...
|
|
203
|
+
* with reasonable confidence that they would be valid if queried).
|
|
204
|
+
*
|
|
205
|
+
* The domain and the tweak together determine the encryption key, which in turn determines the number of rounds of
|
|
206
|
+
* shuffle and xor operations. The minimum number of rounds is 4, except where the domain is less than or equal to 256,
|
|
207
|
+
* which results in single-byte operations. To ensure that the operations are effective for single-byte domains, the
|
|
208
|
+
* number of rounds is 1 and only the xor operation is applied (shuffling a single byte is an identity operation).
|
|
209
|
+
*
|
|
210
|
+
* Another exception is when there is a tweak value of 0; this results in identity operations where the output value is
|
|
211
|
+
* identical to the input value, as no shuffle or xor takes place.
|
|
212
|
+
*/
|
|
213
|
+
export class EncryptionTransformer extends Transformer {
|
|
214
|
+
/**
|
|
215
|
+
* Individual bits, pre-calculated for performance.
|
|
216
|
+
*/
|
|
217
|
+
static BITS = new Uint8Array([
|
|
218
|
+
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
|
|
219
|
+
]);
|
|
220
|
+
/**
|
|
221
|
+
* Inverse individual bits, pre-calculated for performance.
|
|
222
|
+
*/
|
|
223
|
+
static INVERSE_BITS = new Uint8Array([
|
|
224
|
+
0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F
|
|
225
|
+
]);
|
|
226
|
+
/**
|
|
227
|
+
* Number of bytes covered by the domain.
|
|
228
|
+
*/
|
|
229
|
+
_domainBytes;
|
|
230
|
+
/**
|
|
231
|
+
* Xor bytes array generated from the domain and tweak.
|
|
232
|
+
*/
|
|
233
|
+
_xorBytes;
|
|
234
|
+
/**
|
|
235
|
+
* Bits array generated from the domain and tweak.
|
|
236
|
+
*/
|
|
237
|
+
_bits;
|
|
238
|
+
/**
|
|
239
|
+
* Inverse bits array generated from the domain and tweak.
|
|
240
|
+
*/
|
|
241
|
+
_inverseBits;
|
|
242
|
+
/**
|
|
243
|
+
* Number of rounds (length of arrays) generated from the domain and tweak.
|
|
244
|
+
*/
|
|
245
|
+
_rounds;
|
|
246
|
+
/**
|
|
247
|
+
* Constructor.
|
|
248
|
+
*
|
|
249
|
+
* @param domain
|
|
250
|
+
* Domain.
|
|
251
|
+
*
|
|
252
|
+
* @param tweak
|
|
253
|
+
* Tweak.
|
|
254
|
+
*/
|
|
255
|
+
constructor(domain, tweak) {
|
|
256
|
+
super(domain);
|
|
257
|
+
if (tweak < 0n) {
|
|
258
|
+
throw new RangeError(i18nextUtility.t("Transformer.tweakMustBeGreaterThanOrEqualToZero", {
|
|
259
|
+
tweak
|
|
260
|
+
}));
|
|
261
|
+
}
|
|
262
|
+
let domainBytes = 0;
|
|
263
|
+
// The number of bytes in the domain determines the size of the shuffle and xor operations.
|
|
264
|
+
for (let reducedDomainMinusOne = this.domain - 1n; reducedDomainMinusOne !== 0n; reducedDomainMinusOne >>= 8n) {
|
|
265
|
+
domainBytes++;
|
|
266
|
+
}
|
|
267
|
+
this._domainBytes = domainBytes;
|
|
268
|
+
const xorBytes = new Array();
|
|
269
|
+
const bits = new Array();
|
|
270
|
+
const inverseBits = new Array();
|
|
271
|
+
// Key is the product of domain, tweak, and an 8-digit prime to force at least four rounds.
|
|
272
|
+
for (let reducedKey = this.domain * BigInt(tweak) * 603868999n; reducedKey !== 0n; reducedKey >>= 8n) {
|
|
273
|
+
// Extract the least significant byte.
|
|
274
|
+
xorBytes.unshift(Number(BigInt.asUintN(8, reducedKey)));
|
|
275
|
+
// Bit number is the reduced key mod 8.
|
|
276
|
+
const bitNumber = Number(BigInt.asUintN(3, reducedKey));
|
|
277
|
+
// Bits are applied in reverse order so that they don't correlate directly with the key bytes at the same index.
|
|
278
|
+
bits.push(EncryptionTransformer.BITS[bitNumber]);
|
|
279
|
+
inverseBits.push(EncryptionTransformer.INVERSE_BITS[bitNumber]);
|
|
280
|
+
}
|
|
281
|
+
// Domains occupying a single byte will not shuffle and will map all values to themselves for very small domains.
|
|
282
|
+
if (domainBytes === 1) {
|
|
283
|
+
// Determine the lowest possible mask that will cover all values in the domain.
|
|
284
|
+
const domainMask = EncryptionTransformer.BITS.filter(bit => bit < domain).reduce((accumulator, bit) => accumulator | bit, 0);
|
|
285
|
+
// Reduce all xor bytes to a single byte and strip higher bits.
|
|
286
|
+
this._xorBytes = new Uint8Array([xorBytes.reduce((accumulator, xorByte) => accumulator ^ xorByte, 0) & domainMask]);
|
|
287
|
+
// Bits and inverse bits are irrelevant as there will be no shuffling; choose first bit arbitrarily.
|
|
288
|
+
this._bits = new Uint8Array([EncryptionTransformer.BITS[0]]);
|
|
289
|
+
this._inverseBits = new Uint8Array([EncryptionTransformer.INVERSE_BITS[0]]);
|
|
290
|
+
// Everything will be done in one round.
|
|
291
|
+
this._rounds = 1;
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
this._xorBytes = new Uint8Array(xorBytes);
|
|
295
|
+
this._bits = new Uint8Array(bits);
|
|
296
|
+
this._inverseBits = new Uint8Array(inverseBits);
|
|
297
|
+
this._rounds = xorBytes.length;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Convert a value to a byte array big enough to handle the entire domain.
|
|
302
|
+
*
|
|
303
|
+
* @param value
|
|
304
|
+
* Value.
|
|
305
|
+
*
|
|
306
|
+
* @returns
|
|
307
|
+
* Big-endian byte array equivalent to the value.
|
|
308
|
+
*/
|
|
309
|
+
valueToBytes(value) {
|
|
310
|
+
const bytes = new Uint8Array(this._domainBytes);
|
|
311
|
+
// Build byte array in reverse order to get as big-endian.
|
|
312
|
+
for (let index = this._domainBytes - 1, reducedValue = value; index >= 0 && reducedValue !== 0n; index--, reducedValue >>= 8n) {
|
|
313
|
+
bytes[index] = Number(BigInt.asUintN(8, reducedValue));
|
|
314
|
+
}
|
|
315
|
+
return bytes;
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Convert a byte array to a value.
|
|
319
|
+
*
|
|
320
|
+
* @param bytes
|
|
321
|
+
* Big-endian byte array equivalent to the value.
|
|
322
|
+
*
|
|
323
|
+
* @returns
|
|
324
|
+
* Value.
|
|
325
|
+
*/
|
|
326
|
+
static bytesToValue(bytes) {
|
|
327
|
+
return bytes.reduce((accumulator, byte) => accumulator << 8n | BigInt(byte), 0n);
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Shuffle a byte array.
|
|
331
|
+
*
|
|
332
|
+
* The input array to the forward operation (output from the reverse operation) is `bytes` and the output array from
|
|
333
|
+
* the forward operation (input to the reverse operation) is `bytes'`.
|
|
334
|
+
*
|
|
335
|
+
* The shuffle operation starts by testing the bit at `bits[round]` for each `byte` in `bytes`. The indexes for all
|
|
336
|
+
* bytes with that bit set are put into one array (`shuffleIndexes1`) and the rest are put into another
|
|
337
|
+
* (`shuffleIndexes0`). The two arrays are concatenated and used to shuffle the input array, using their values
|
|
338
|
+
* (`shuffleIndex`) and the indexes of those values (`index`) in the concatenated array.
|
|
339
|
+
*
|
|
340
|
+
* Forward shuffling moves the entry at `shuffleIndex` to the `index` position.
|
|
341
|
+
*
|
|
342
|
+
* Reverse shuffling moves the entry at `index` to the `shuffleIndex` position.
|
|
343
|
+
*
|
|
344
|
+
* As each byte is moved, the bit at `bits[round]` is preserved in its original position. This ensures that the
|
|
345
|
+
* process is reversible.
|
|
346
|
+
*
|
|
347
|
+
* @param bytes
|
|
348
|
+
* Byte array.
|
|
349
|
+
*
|
|
350
|
+
* @param round
|
|
351
|
+
* Round number.
|
|
352
|
+
*
|
|
353
|
+
* @param forward
|
|
354
|
+
* True if operating forward (encrypting), false if operating in reverse (decrypting).
|
|
355
|
+
*
|
|
356
|
+
* @returns
|
|
357
|
+
* Shuffled byte array.
|
|
358
|
+
*/
|
|
359
|
+
shuffle(bytes, round, forward) {
|
|
360
|
+
const bytesLength = bytes.length;
|
|
361
|
+
const determinants = new Uint8Array(bytesLength);
|
|
362
|
+
const shuffleIndexes1 = new Array();
|
|
363
|
+
const shuffleIndexes0 = new Array();
|
|
364
|
+
const bit = this._bits[round];
|
|
365
|
+
bytes.forEach((byte, index) => {
|
|
366
|
+
const determinant = byte & bit;
|
|
367
|
+
determinants[index] = determinant;
|
|
368
|
+
// Place byte in array chosen by bit state.
|
|
369
|
+
(determinant !== 0 ? shuffleIndexes1 : shuffleIndexes0).push(index);
|
|
370
|
+
});
|
|
371
|
+
const inverseBit = this._inverseBits[round];
|
|
372
|
+
const shuffleBytes = new Uint8Array(bytesLength);
|
|
373
|
+
// Concatenate shuffle indexes arrays and complete shuffle.
|
|
374
|
+
[...shuffleIndexes1, ...shuffleIndexes0].forEach((shuffleIndex, index) => {
|
|
375
|
+
if (forward) {
|
|
376
|
+
shuffleBytes[index] = (bytes[shuffleIndex] & inverseBit) | determinants[index];
|
|
377
|
+
}
|
|
378
|
+
else {
|
|
379
|
+
shuffleBytes[shuffleIndex] = (bytes[index] & inverseBit) | determinants[shuffleIndex];
|
|
380
|
+
}
|
|
381
|
+
});
|
|
382
|
+
return shuffleBytes;
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Xor a byte array.
|
|
386
|
+
*
|
|
387
|
+
* The input array to the forward operation (output from the reverse operation) is `bytes` and the output array from
|
|
388
|
+
* the forward operation (input to the reverse operation) is `bytes'`.
|
|
389
|
+
*
|
|
390
|
+
* Forward:
|
|
391
|
+
* - `bytes'[0] = bytes[0] ^ xorBytes[round]`
|
|
392
|
+
* - `bytes'[1] = bytes[1] ^ bytes'[0]`
|
|
393
|
+
* - `bytes'[2] = bytes[2] ^ bytes'[1]`
|
|
394
|
+
* - `...`
|
|
395
|
+
* - `bytes'[domainBytes - 1] = bytes[domainBytes - 1] ^ bytes'[domainBytes - 2]`
|
|
396
|
+
*
|
|
397
|
+
* Reverse:
|
|
398
|
+
* - `bytes[0] = bytes'[0] ^ xorBytes[round]`
|
|
399
|
+
* - `bytes[1] = bytes'[1] ^ bytes'[0]`
|
|
400
|
+
* - `bytes[2] = bytes'[2] ^ bytes'[1]`
|
|
401
|
+
* - `...`
|
|
402
|
+
* - `bytes[domainBytes - 1] = bytes'[domainBytes - 1] ^ bytes'[domainBytes - 2]`
|
|
403
|
+
*
|
|
404
|
+
* @param bytes
|
|
405
|
+
* Byte array.
|
|
406
|
+
*
|
|
407
|
+
* @param round
|
|
408
|
+
* Round number.
|
|
409
|
+
*
|
|
410
|
+
* @param forward
|
|
411
|
+
* True if operating forward (encrypting), false if operating in reverse (decrypting).
|
|
412
|
+
*
|
|
413
|
+
* @returns
|
|
414
|
+
* Xored byte array.
|
|
415
|
+
*/
|
|
416
|
+
xor(bytes, round, forward) {
|
|
417
|
+
let cumulativeXorByte = this._xorBytes[round];
|
|
418
|
+
return bytes.map((byte) => {
|
|
419
|
+
const xorByte = byte ^ cumulativeXorByte;
|
|
420
|
+
cumulativeXorByte = forward ? xorByte : byte;
|
|
421
|
+
return xorByte;
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* @inheritDoc
|
|
426
|
+
*/
|
|
427
|
+
doForward(value) {
|
|
428
|
+
let bytes = this.valueToBytes(value);
|
|
429
|
+
let transformedValue;
|
|
430
|
+
// Loop repeats until transformed value is within domain.
|
|
431
|
+
do {
|
|
432
|
+
// Forward operation is shuffle then xor for the number of rounds.
|
|
433
|
+
for (let round = 0; round < this._rounds; round++) {
|
|
434
|
+
bytes = this.xor(this.shuffle(bytes, round, true), round, true);
|
|
435
|
+
}
|
|
436
|
+
transformedValue = EncryptionTransformer.bytesToValue(bytes);
|
|
437
|
+
} while (transformedValue >= this.domain);
|
|
438
|
+
return transformedValue;
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* @inheritDoc
|
|
442
|
+
*/
|
|
443
|
+
doReverse(transformedValue) {
|
|
444
|
+
let bytes = this.valueToBytes(transformedValue);
|
|
445
|
+
let value;
|
|
446
|
+
// Loop repeats until value is within domain.
|
|
447
|
+
do {
|
|
448
|
+
// Reverse operation is xor then shuffle for the number of rounds in reverse.
|
|
449
|
+
for (let round = this._rounds - 1; round >= 0; round--) {
|
|
450
|
+
bytes = this.shuffle(this.xor(bytes, round, false), round, false);
|
|
451
|
+
}
|
|
452
|
+
value = EncryptionTransformer.bytesToValue(bytes);
|
|
453
|
+
} while (value >= this.domain);
|
|
454
|
+
return value;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
//# sourceMappingURL=transformer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transformer.js","sourceRoot":"","sources":["../src/transformer.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aidc-toolkit/utility",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.26-beta",
|
|
4
4
|
"description": "Foundational utilities for AIDC Toolkit",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"homepage": "https://aidc-toolkit.com/",
|
|
8
|
-
"repository":
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/aidc-toolkit/utility.git"
|
|
11
|
+
},
|
|
9
12
|
"bugs": {
|
|
10
13
|
"url": "https://github.com/aidc-toolkit/utility/issues"
|
|
11
14
|
},
|
|
@@ -17,16 +20,17 @@
|
|
|
17
20
|
},
|
|
18
21
|
"scripts": {
|
|
19
22
|
"lint": "eslint",
|
|
20
|
-
"
|
|
21
|
-
"build:
|
|
23
|
+
"tsc:core": "tsc --project tsconfig-src.json",
|
|
24
|
+
"build:dev": "rimraf dist && npm run tsc:core -- --declarationMap --sourceMap",
|
|
25
|
+
"build:release": "npm run tsc:core -- --noEmit && tsup",
|
|
22
26
|
"build:doc": "npm run build:dev",
|
|
23
27
|
"test": "vitest run"
|
|
24
28
|
},
|
|
25
29
|
"devDependencies": {
|
|
26
|
-
"@aidc-toolkit/dev": "beta",
|
|
27
|
-
"vitest": "^4.0.
|
|
30
|
+
"@aidc-toolkit/dev": "1.0.26-beta",
|
|
31
|
+
"vitest": "^4.0.15"
|
|
28
32
|
},
|
|
29
33
|
"dependencies": {
|
|
30
|
-
"@aidc-toolkit/core": "beta"
|
|
34
|
+
"@aidc-toolkit/core": "1.0.26-beta"
|
|
31
35
|
}
|
|
32
36
|
}
|
package/src/character-set.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { type Exclusion, Exclusions } from "./exclusion";
|
|
2
|
-
import type { IndexedCallback } from "./iterable-utility";
|
|
3
|
-
import { i18nextUtility } from "./locale/i18n";
|
|
4
|
-
import { RegExpValidator } from "./reg-exp";
|
|
5
|
-
import type { StringValidation, StringValidator } from "./string";
|
|
6
|
-
import { Transformer, type TransformerInput, type TransformerOutput } from "./transformer";
|
|
1
|
+
import { type Exclusion, Exclusions } from "./exclusion.js";
|
|
2
|
+
import type { IndexedCallback } from "./iterable-utility.js";
|
|
3
|
+
import { i18nextUtility } from "./locale/i18n.js";
|
|
4
|
+
import { RegExpValidator } from "./reg-exp.js";
|
|
5
|
+
import type { StringValidation, StringValidator } from "./string.js";
|
|
6
|
+
import { Transformer, type TransformerInput, type TransformerOutput } from "./transformer.js";
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Character set validation parameters.
|
|
@@ -81,7 +81,7 @@ export class CharacterSetValidator implements StringValidator<CharacterSetValida
|
|
|
81
81
|
* set.
|
|
82
82
|
*
|
|
83
83
|
* @param exclusionSupport
|
|
84
|
-
* Exclusions supported by the character set. All character sets implicitly support {@
|
|
84
|
+
* Exclusions supported by the character set. All character sets implicitly support {@linkcode Exclusions.None}.
|
|
85
85
|
*/
|
|
86
86
|
constructor(characterSet: readonly string[], ...exclusionSupport: readonly Exclusion[]) {
|
|
87
87
|
this._characterSet = characterSet;
|
|
@@ -324,7 +324,7 @@ export class CharacterSetCreator extends CharacterSetValidator {
|
|
|
324
324
|
private readonly _characterSetSizeMinusOneN: bigint;
|
|
325
325
|
|
|
326
326
|
/**
|
|
327
|
-
* Domains for every length for every supported {@
|
|
327
|
+
* Domains for every length for every supported {@linkcode Exclusions}.
|
|
328
328
|
*/
|
|
329
329
|
private readonly _exclusionDomains: ReadonlyArray<readonly bigint[]>;
|
|
330
330
|
|
|
@@ -341,7 +341,7 @@ export class CharacterSetCreator extends CharacterSetValidator {
|
|
|
341
341
|
* set.
|
|
342
342
|
*
|
|
343
343
|
* @param exclusionSupport
|
|
344
|
-
* Exclusions supported by the character set. All character sets implicitly support {@
|
|
344
|
+
* Exclusions supported by the character set. All character sets implicitly support {@linkcode Exclusions.None}.
|
|
345
345
|
*/
|
|
346
346
|
constructor(characterSet: readonly string[], ...exclusionSupport: readonly Exclusion[]) {
|
|
347
347
|
super(characterSet, ...exclusionSupport);
|
|
@@ -488,7 +488,7 @@ export class CharacterSetCreator extends CharacterSetValidator {
|
|
|
488
488
|
}
|
|
489
489
|
|
|
490
490
|
/**
|
|
491
|
-
* Validate that a length is less than or equal to {@
|
|
491
|
+
* Validate that a length is less than or equal to {@linkcode MAXIMUM_STRING_LENGTH}. If not, an error is thrown.
|
|
492
492
|
*
|
|
493
493
|
* @param length
|
|
494
494
|
* Length.
|
|
@@ -523,7 +523,8 @@ export class CharacterSetCreator extends CharacterSetValidator {
|
|
|
523
523
|
* Numeric value(s) of the string(s).
|
|
524
524
|
*
|
|
525
525
|
* @param exclusion
|
|
526
|
-
* String(s) to be excluded from the range of outputs. See {@
|
|
526
|
+
* String(s) to be excluded from the range of outputs. See {@linkcode Exclusions} for possible values and their
|
|
527
|
+
* meaning.
|
|
527
528
|
*
|
|
528
529
|
* @param tweak
|
|
529
530
|
* If provided, the numerical value of the string(s) is/are "tweaked" using an {@link EncryptionTransformer |
|
|
@@ -553,7 +554,7 @@ export class CharacterSetCreator extends CharacterSetValidator {
|
|
|
553
554
|
|
|
554
555
|
if (exclusion === Exclusions.AllNumeric && convertValue >= allZerosValue) {
|
|
555
556
|
// Value to convert is shifted by the number of all-numeric strings that occur at or prior to it.
|
|
556
|
-
convertValue
|
|
557
|
+
convertValue += this.allNumericShift(true, length, convertValue - allZerosValue);
|
|
557
558
|
}
|
|
558
559
|
|
|
559
560
|
// Build string from right to left excluding the first character.
|
|
@@ -581,7 +582,7 @@ export class CharacterSetCreator extends CharacterSetValidator {
|
|
|
581
582
|
* String.
|
|
582
583
|
*
|
|
583
584
|
* @param exclusion
|
|
584
|
-
* Strings excluded from the range of inputs. See {@
|
|
585
|
+
* Strings excluded from the range of inputs. See {@linkcode Exclusions} for possible values and their meaning.
|
|
585
586
|
*
|
|
586
587
|
* @param tweak
|
|
587
588
|
* If provided, the numerical value of the string was "tweaked" using an {@link EncryptionTransformer | encryption
|
|
@@ -640,19 +641,19 @@ export class CharacterSetCreator extends CharacterSetValidator {
|
|
|
640
641
|
}
|
|
641
642
|
|
|
642
643
|
/**
|
|
643
|
-
* Numeric creator. Character set is 0-9. Supports {@
|
|
644
|
+
* Numeric creator. Character set is 0-9. Supports {@linkcode Exclusions.FirstZero}.
|
|
644
645
|
*/
|
|
645
646
|
export const NUMERIC_CREATOR = new CharacterSetCreator([
|
|
646
647
|
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
|
|
647
648
|
], Exclusions.FirstZero);
|
|
648
649
|
|
|
649
650
|
/**
|
|
650
|
-
* Numeric validator. Character set is 0-9. Supports {@
|
|
651
|
+
* Numeric validator. Character set is 0-9. Supports {@linkcode Exclusions.FirstZero}.
|
|
651
652
|
*/
|
|
652
653
|
export const NUMERIC_VALIDATOR = NUMERIC_CREATOR as CharacterSetValidator;
|
|
653
654
|
|
|
654
655
|
/**
|
|
655
|
-
* Hexadecimal creator. Character set is 0-9, A-F. Supports {@
|
|
656
|
+
* Hexadecimal creator. Character set is 0-9, A-F. Supports {@linkcode Exclusions.FirstZero} and {@linkcode
|
|
656
657
|
* Exclusions.AllNumeric}.
|
|
657
658
|
*/
|
|
658
659
|
export const HEXADECIMAL_CREATOR = new CharacterSetCreator([
|
|
@@ -661,7 +662,7 @@ export const HEXADECIMAL_CREATOR = new CharacterSetCreator([
|
|
|
661
662
|
], Exclusions.FirstZero, Exclusions.AllNumeric);
|
|
662
663
|
|
|
663
664
|
/**
|
|
664
|
-
* Hexadecimal validator. Character set is 0-9, A-F. Supports {@
|
|
665
|
+
* Hexadecimal validator. Character set is 0-9, A-F. Supports {@linkcode Exclusions.FirstZero} and {@linkcode
|
|
665
666
|
* Exclusions.AllNumeric}.
|
|
666
667
|
*/
|
|
667
668
|
export const HEXADECIMAL_VALIDATOR = HEXADECIMAL_CREATOR as CharacterSetValidator;
|
|
@@ -680,7 +681,7 @@ export const ALPHABETIC_CREATOR = new CharacterSetCreator([
|
|
|
680
681
|
export const ALPHABETIC_VALIDATOR = ALPHABETIC_CREATOR as CharacterSetValidator;
|
|
681
682
|
|
|
682
683
|
/**
|
|
683
|
-
* Alphanumeric creator. Character set is 0-9, A-Z. Supports {@
|
|
684
|
+
* Alphanumeric creator. Character set is 0-9, A-Z. Supports {@linkcode Exclusions.FirstZero} and {@linkcode
|
|
684
685
|
* Exclusions.AllNumeric}.
|
|
685
686
|
*/
|
|
686
687
|
export const ALPHANUMERIC_CREATOR = new CharacterSetCreator([
|
|
@@ -690,7 +691,7 @@ export const ALPHANUMERIC_CREATOR = new CharacterSetCreator([
|
|
|
690
691
|
], Exclusions.FirstZero, Exclusions.AllNumeric);
|
|
691
692
|
|
|
692
693
|
/**
|
|
693
|
-
* Alphanumeric validator. Character set is 0-9, A-Z. Supports {@
|
|
694
|
+
* Alphanumeric validator. Character set is 0-9, A-Z. Supports {@linkcode Exclusions.FirstZero} and {@linkcode
|
|
694
695
|
* Exclusions.AllNumeric}.
|
|
695
696
|
*/
|
|
696
697
|
export const ALPHANUMERIC_VALIDATOR = ALPHANUMERIC_CREATOR as CharacterSetValidator;
|
package/src/exclusion.ts
CHANGED
|
@@ -18,7 +18,12 @@ export const Exclusions = {
|
|
|
18
18
|
AllNumeric: 2
|
|
19
19
|
} as const;
|
|
20
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Exclusion key.
|
|
23
|
+
*/
|
|
24
|
+
export type ExclusionKey = keyof typeof Exclusions;
|
|
25
|
+
|
|
21
26
|
/**
|
|
22
27
|
* Exclusion.
|
|
23
28
|
*/
|
|
24
|
-
export type Exclusion = typeof Exclusions[
|
|
29
|
+
export type Exclusion = typeof Exclusions[ExclusionKey];
|