nhb-toolbox 4.27.10 → 4.28.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.
Files changed (44) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cjs/date/constants.js +62 -2
  3. package/dist/cjs/date/guards.js +10 -3
  4. package/dist/cjs/date/parse.js +33 -0
  5. package/dist/cjs/hash/Cipher.js +73 -0
  6. package/dist/cjs/hash/Signet.js +168 -0
  7. package/dist/cjs/hash/core.js +89 -0
  8. package/dist/cjs/hash/helpers.js +130 -63
  9. package/dist/cjs/hash/index.js +34 -243
  10. package/dist/cjs/hash/utils.js +252 -0
  11. package/dist/cjs/hash/uuid.js +168 -0
  12. package/dist/cjs/index.js +12 -6
  13. package/dist/cjs/string/basics.js +16 -16
  14. package/dist/cjs/utils/index.js +27 -0
  15. package/dist/dts/date/constants.d.ts +18 -3
  16. package/dist/dts/date/guards.d.ts +3 -1
  17. package/dist/dts/date/parse.d.ts +14 -0
  18. package/dist/dts/date/types.d.ts +7 -1
  19. package/dist/dts/hash/Cipher.d.ts +45 -0
  20. package/dist/dts/hash/Signet.d.ts +444 -0
  21. package/dist/dts/hash/core.d.ts +66 -0
  22. package/dist/dts/hash/helpers.d.ts +16 -5
  23. package/dist/dts/hash/index.d.ts +7 -147
  24. package/dist/dts/hash/types.d.ts +90 -1
  25. package/dist/dts/hash/utils.d.ts +348 -0
  26. package/dist/dts/hash/uuid.d.ts +91 -0
  27. package/dist/dts/index.d.ts +3 -2
  28. package/dist/dts/string/basics.d.ts +48 -3
  29. package/dist/dts/string/types.d.ts +3 -3
  30. package/dist/dts/utils/index.d.ts +26 -0
  31. package/dist/esm/date/constants.js +61 -1
  32. package/dist/esm/date/guards.js +10 -4
  33. package/dist/esm/date/parse.js +30 -0
  34. package/dist/esm/hash/Cipher.js +69 -0
  35. package/dist/esm/hash/Signet.js +164 -0
  36. package/dist/esm/hash/core.js +84 -0
  37. package/dist/esm/hash/helpers.js +122 -61
  38. package/dist/esm/hash/index.js +7 -231
  39. package/dist/esm/hash/utils.js +239 -0
  40. package/dist/esm/hash/uuid.js +156 -0
  41. package/dist/esm/index.js +3 -2
  42. package/dist/esm/string/basics.js +14 -13
  43. package/dist/esm/utils/index.js +26 -1
  44. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -6,6 +6,18 @@ All notable changes to the package will be documented here.
6
6
 
7
7
  ---
8
8
 
9
+ ## [4.28.0] - 2025-12-01
10
+
11
+ - **Added** *new* class `Cipher` to *encrypt/decrypt* string with *secret key*.
12
+ - **Added** *new* class `Signet` to *sign*, *decode* and *verify* **token** like `JWT`.
13
+ - **Added** *new* `sha256` hash function. **Updated** `sha1` *encoding algorithm*. Now it avoids depending on `TextEncoder`.
14
+ - **Added** *new* utility `parseMSec` to convert time value to *milliseconds* or *seconds* along with new *type guard* `isTimeWithUnit`.
15
+ - **Added** *new* `JSON` utilities: `stableStringify` for *stable, deterministic stringifying* and `stripJsonEdgeGarbage` for stripping `JSON` string.
16
+
17
+ ## [4.27.11] - 2025-11-29
18
+
19
+ - **Updated** *core algorithms* of `md5` and `sha1` utilities to fix *incorrect hash digest generation*.
20
+
9
21
  ## [4.27.10] - 2025-11-28
10
22
 
11
23
  - **Updated** type augmentation for `String` methods: `toLowerCase` and `toUpperCase` (type level only, implementation remains intact).
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.INTERNALS = exports.ZODIAC_PRESETS = exports.VEDIC_ZODIAC_SIGNS = exports.WESTERN_ZODIAC_SIGNS = exports.DATE_PART_RANGES = exports.SORTED_TIME_FORMATS = exports.TIME_FORMATS = exports.MILLISECOND_FORMATS = exports.ZONE_FORMATS = exports.SECOND_FORMATS = exports.MINUTE_FORMATS = exports.HOUR_FORMATS = exports.DAY_FORMATS = exports.DATE_FORMATS = exports.MONTH_FORMATS = exports.YEAR_FORMATS = exports.MONTHS = exports.DAYS = void 0;
3
+ exports.MS_MAP = exports.TIME_UNIT_REGEX = exports.TIME_UNIT_VARIANTS = exports.ZODIAC_PRESETS = exports.VEDIC_ZODIAC_SIGNS = exports.WESTERN_ZODIAC_SIGNS = exports.DATE_PART_RANGES = exports.SORTED_TIME_FORMATS = exports.TIME_FORMATS = exports.MILLISECOND_FORMATS = exports.ZONE_FORMATS = exports.SECOND_FORMATS = exports.MINUTE_FORMATS = exports.HOUR_FORMATS = exports.DAY_FORMATS = exports.DATE_FORMATS = exports.MONTH_FORMATS = exports.YEAR_FORMATS = exports.MONTHS = exports.DAYS = exports.INTERNALS = void 0;
4
+ exports.INTERNALS = Symbol('Internals');
4
5
  exports.DAYS = /* @__PURE__ */ Object.freeze([
5
6
  'Sunday',
6
7
  'Monday',
@@ -95,4 +96,63 @@ exports.ZODIAC_PRESETS = /* @__PURE__ */ Object.freeze({
95
96
  tropical: exports.WESTERN_ZODIAC_SIGNS,
96
97
  sidereal: exports.VEDIC_ZODIAC_SIGNS,
97
98
  });
98
- exports.INTERNALS = Symbol('Internals');
99
+ exports.TIME_UNIT_VARIANTS = /* @__PURE__ */ Object.freeze({
100
+ year: ['y', 'yr', 'yrs', 'year', 'years'],
101
+ month: ['mo', 'month', 'months'],
102
+ week: ['w', 'week', 'weeks'],
103
+ day: ['d', 'day', 'days'],
104
+ hour: ['h', 'hr', 'hrs', 'hour', 'hours'],
105
+ minute: ['m', 'min', 'mins', 'minute', 'minutes'],
106
+ second: ['s', 'sec', 'secs', 'second', 'seconds'],
107
+ millisecond: ['ms', 'msec', 'msecs', 'millisecond', 'milliseconds'],
108
+ });
109
+ const TIME_UNIT_REGEX_STR = /* @__PURE__ */ Object.freeze(Object.values(exports.TIME_UNIT_VARIANTS)
110
+ .flat()
111
+ .sort((a, b) => b.length - a.length)
112
+ .join('|'));
113
+ exports.TIME_UNIT_REGEX = /* @__PURE__ */ Object.freeze(new RegExp(`^(?<value>-?\\d*\\.?\\d+) *(?<unit>${TIME_UNIT_REGEX_STR})?$`, 'i'));
114
+ exports.MS_MAP = /* @__PURE__ */ Object.freeze((() => {
115
+ const s = 1000;
116
+ const m = s * 60;
117
+ const h = m * 60;
118
+ const d = h * 24;
119
+ const w = d * 7;
120
+ const y = d * 365.25;
121
+ const mo = y / 12;
122
+ return {
123
+ y,
124
+ yr: y,
125
+ yrs: y,
126
+ year: y,
127
+ years: y,
128
+ mo,
129
+ month: mo,
130
+ months: mo,
131
+ w,
132
+ week: w,
133
+ weeks: w,
134
+ d,
135
+ day: d,
136
+ days: d,
137
+ h,
138
+ hr: h,
139
+ hrs: h,
140
+ hour: h,
141
+ hours: h,
142
+ m,
143
+ min: m,
144
+ mins: m,
145
+ minute: m,
146
+ minutes: m,
147
+ s,
148
+ sec: s,
149
+ secs: s,
150
+ second: s,
151
+ seconds: s,
152
+ ms: 1,
153
+ msec: 1,
154
+ msecs: 1,
155
+ millisecond: 1,
156
+ milliseconds: 1,
157
+ };
158
+ })());
@@ -6,12 +6,14 @@ exports.isValidTimeZoneId = isValidTimeZoneId;
6
6
  exports.isNativeTimeZoneId = isNativeTimeZoneId;
7
7
  exports.isLeapYear = isLeapYear;
8
8
  exports.isDateLike = isDateLike;
9
+ exports.isTimeWithUnit = isTimeWithUnit;
9
10
  const primitives_1 = require("../guards/primitives");
10
11
  const specials_1 = require("../guards/specials");
11
12
  const utilities_1 = require("../number/utilities");
13
+ const constants_1 = require("./constants");
12
14
  const timezone_1 = require("./timezone");
13
15
  function isValidTime(value) {
14
- if (!(0, primitives_1.isString)(value))
16
+ if (!(0, primitives_1.isNonEmptyString)(value))
15
17
  return false;
16
18
  const [hourStr, minuteStr] = value.split(':');
17
19
  if (!(0, specials_1.isNumericString)(hourStr) || !(0, specials_1.isNumericString)(minuteStr))
@@ -24,10 +26,12 @@ function isValidUTCOffset(value) {
24
26
  return (0, primitives_1.isString)(value) ? /^UTC[+-]?\d{1,2}:\d{2}$/.test(value) : false;
25
27
  }
26
28
  function isValidTimeZoneId(value) {
27
- return (0, primitives_1.isString)(value) ? [...timezone_1.IANA_TZ_IDS].includes(value) : false;
29
+ return (0, primitives_1.isNonEmptyString)(value) ? new Set([...timezone_1.IANA_TZ_IDS]).has(value) : false;
28
30
  }
29
31
  function isNativeTimeZoneId(value) {
30
- return (0, primitives_1.isString)(value) ? Intl.supportedValuesOf('timeZone').includes(value) : false;
32
+ return (0, primitives_1.isNonEmptyString)(value) ?
33
+ new Set(Intl.supportedValuesOf('timeZone')).has(value)
34
+ : false;
31
35
  }
32
36
  function isLeapYear(year) {
33
37
  const $year = (0, utilities_1.normalizeNumber)(year);
@@ -62,3 +66,6 @@ function isDateLike(value) {
62
66
  }
63
67
  return false;
64
68
  }
69
+ function isTimeWithUnit(value) {
70
+ return (0, primitives_1.isNonEmptyString)(value) && constants_1.TIME_UNIT_REGEX.test(value);
71
+ }
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseMSec = parseMSec;
4
+ const primitives_1 = require("../guards/primitives");
5
+ const specials_1 = require("../guards/specials");
6
+ const constants_1 = require("./constants");
7
+ const guards_1 = require("./guards");
8
+ function parseMSec(value, sec = false) {
9
+ if ((0, specials_1.isNumericString)(value)) {
10
+ return _parse(`${value}s`, sec);
11
+ }
12
+ else if ((0, guards_1.isTimeWithUnit)(value)) {
13
+ return _parse(value, sec);
14
+ }
15
+ else if ((0, primitives_1.isNumber)(value)) {
16
+ return _parse(`${value}s`, sec);
17
+ }
18
+ return NaN;
19
+ }
20
+ function _parse(str, sec = false) {
21
+ if (!(0, primitives_1.isNonEmptyString)(str) || str.length > 100) {
22
+ throw new RangeError(`Value must be a string with length between 1 and 99!`);
23
+ }
24
+ const match = constants_1.TIME_UNIT_REGEX.exec(str);
25
+ if (!match?.groups)
26
+ return NaN;
27
+ const unit = (match.groups.unit ?? 'ms').toLowerCase();
28
+ const multiplier = constants_1.MS_MAP[unit];
29
+ if (!multiplier)
30
+ throw new RangeError(`Unknown unit "${unit}"!`);
31
+ const ms = parseFloat(match.groups.value) * multiplier;
32
+ return sec ? ms / 1000 : ms;
33
+ }
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Cipher = void 0;
4
+ const primitives_1 = require("../guards/primitives");
5
+ const specials_1 = require("../guards/specials");
6
+ const helpers_1 = require("./helpers");
7
+ const utils_1 = require("./utils");
8
+ class Cipher {
9
+ #secretBytes;
10
+ #encKey;
11
+ #macKey;
12
+ constructor(secret) {
13
+ if (!(0, primitives_1.isNonEmptyString)(secret)) {
14
+ throw new Error('Secret must be non-empty string!');
15
+ }
16
+ this.#secretBytes = (0, utils_1.utf8ToBytes)(secret);
17
+ this.#encKey = (0, utils_1.hmacSha256)(this.#secretBytes, (0, utils_1.utf8ToBytes)('enc'));
18
+ this.#macKey = (0, utils_1.hmacSha256)(this.#secretBytes, (0, utils_1.utf8ToBytes)('mac'));
19
+ }
20
+ #genKeystream(target, iv) {
21
+ const blocks = Math.ceil(target.length / 32);
22
+ const keystreamParts = [];
23
+ for (let counter = 0; counter < blocks; counter++) {
24
+ keystreamParts.push((0, utils_1.hmacSha256)(this.#encKey, (0, utils_1.concatBytes)(iv, (0, utils_1.intTo4BytesBE)(counter))));
25
+ }
26
+ return (0, utils_1.concatBytes)(...keystreamParts).subarray(0, target.length);
27
+ }
28
+ encrypt(text) {
29
+ const plain = (0, utils_1.utf8ToBytes)(text);
30
+ const seed = (0, utils_1.utf8ToBytes)(String(Date.now()) + '-' + String(Math.random()));
31
+ const ivFull = (0, utils_1.sha256Bytes)(seed);
32
+ const iv = ivFull.subarray(0, 16);
33
+ const keystream = this.#genKeystream(plain, iv);
34
+ const ct = new Uint8Array(plain.length);
35
+ for (let i = 0; i < plain.length; i++)
36
+ ct[i] = plain[i] ^ keystream[i];
37
+ const tag = (0, utils_1.hmacSha256)(this.#macKey, (0, utils_1.concatBytes)(iv, ct));
38
+ const blob = (0, utils_1.concatBytes)(iv, ct, tag);
39
+ return (0, utils_1.bytesToBase64)(blob);
40
+ }
41
+ isValid(token) {
42
+ if (!(0, specials_1.isBase64)(token))
43
+ return false;
44
+ const blob = (0, utils_1.base64ToBytes)(token);
45
+ if (blob.length < 48)
46
+ return false;
47
+ const iv = blob.subarray(0, 16);
48
+ const tag = blob.subarray(blob.length - 32);
49
+ const ct = blob.subarray(16, blob.length - 32);
50
+ const expectedTag = (0, utils_1.hmacSha256)(this.#macKey, (0, utils_1.concatBytes)(iv, ct));
51
+ return (0, helpers_1._constantTimeEquals)(expectedTag, tag);
52
+ }
53
+ decrypt(token) {
54
+ if (!(0, specials_1.isBase64)(token))
55
+ throw new Error('Token must be a base64 string!');
56
+ const blob = (0, utils_1.base64ToBytes)(token);
57
+ if (blob.length < 48)
58
+ throw new Error('Malformed or tampered token!');
59
+ const iv = blob.subarray(0, 16);
60
+ const tag = blob.subarray(blob.length - 32);
61
+ const ct = blob.subarray(16, blob.length - 32);
62
+ const expectedTag = (0, utils_1.hmacSha256)(this.#macKey, (0, utils_1.concatBytes)(iv, ct));
63
+ if (!(0, helpers_1._constantTimeEquals)(expectedTag, tag)) {
64
+ throw new Error('Key in the token is tampered or invalid!)');
65
+ }
66
+ const keystream = this.#genKeystream(ct, iv);
67
+ const pt = new Uint8Array(ct.length);
68
+ for (let i = 0; i < ct.length; i++)
69
+ pt[i] = ct[i] ^ keystream[i];
70
+ return (0, utils_1.bytesToUtf8)(pt);
71
+ }
72
+ }
73
+ exports.Cipher = Cipher;
@@ -0,0 +1,168 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Signet = void 0;
4
+ const parse_1 = require("../date/parse");
5
+ const non_primitives_1 = require("../guards/non-primitives");
6
+ const primitives_1 = require("../guards/primitives");
7
+ const index_1 = require("../utils/index");
8
+ const helpers_1 = require("./helpers");
9
+ const utils_1 = require("./utils");
10
+ class Signet {
11
+ #secretBytes;
12
+ constructor(secret) {
13
+ if (!(0, primitives_1.isNonEmptyString)(secret)) {
14
+ throw new Error('Secret must be a non-empty string!');
15
+ }
16
+ this.#secretBytes = (0, utils_1.utf8ToBytes)(secret);
17
+ }
18
+ #decode(token) {
19
+ if (!(0, primitives_1.isNonEmptyString)(token)) {
20
+ throw new Error('Token must be a non-empty string!');
21
+ }
22
+ const parts = token.split('.');
23
+ if (parts.length !== 3) {
24
+ throw new Error('Token is tampered or malformed!');
25
+ }
26
+ const [hdr, pld, signature] = parts;
27
+ const headerBytes = (0, utils_1.base64ToBytes)(hdr);
28
+ const payloadBytes = (0, utils_1.base64ToBytes)(pld);
29
+ const headerStr = (0, index_1.stripJsonEdgeGarbage)((0, utils_1.bytesToUtf8)(headerBytes));
30
+ const payloadStr = (0, index_1.stripJsonEdgeGarbage)((0, utils_1.bytesToUtf8)(payloadBytes));
31
+ let header;
32
+ try {
33
+ header = JSON.parse(headerStr);
34
+ }
35
+ catch {
36
+ throw new Error('Cannot parse header!');
37
+ }
38
+ let payload;
39
+ try {
40
+ const { iat, iatDate, exp, expDate, nbf, nbfDate, aud, sub, iss, ...rest } = JSON.parse(payloadStr);
41
+ payload = {
42
+ iat,
43
+ iatDate: iatDate ? new Date(iatDate) : (0, helpers_1._secToDate)(iat),
44
+ ...(exp && { exp }),
45
+ ...(exp && { expDate: expDate ? new Date(expDate) : (0, helpers_1._secToDate)(exp) }),
46
+ ...(nbf && { nbf }),
47
+ ...(nbf && { nbfDate: nbfDate ? new Date(nbfDate) : (0, helpers_1._secToDate)(nbf) }),
48
+ ...(aud && { aud }),
49
+ ...(sub && { sub }),
50
+ ...(iss && { iss }),
51
+ ...rest,
52
+ };
53
+ }
54
+ catch {
55
+ throw new Error('Cannot parse payload!');
56
+ }
57
+ return {
58
+ header,
59
+ payload,
60
+ signature,
61
+ signingInput: `${hdr}.${pld}`,
62
+ };
63
+ }
64
+ sign(payload, options) {
65
+ if (!(0, non_primitives_1.isNotEmptyObject)(payload))
66
+ throw new Error('Payload must be a valid object!');
67
+ const { expiresIn, notBefore, audience, issuer, subject } = options || {};
68
+ const iat = (0, helpers_1._toSeconds)(Date.now());
69
+ const $payload = {
70
+ iat,
71
+ iatDate: (0, helpers_1._secToDate)(iat),
72
+ ...(expiresIn && { exp: iat + (0, helpers_1._toSeconds)((0, parse_1.parseMSec)(expiresIn)) }),
73
+ ...(expiresIn && { expDate: (0, helpers_1._secToDate)(iat + (0, helpers_1._toSeconds)((0, parse_1.parseMSec)(expiresIn))) }),
74
+ ...(notBefore && { nbf: iat + (0, helpers_1._toSeconds)((0, parse_1.parseMSec)(notBefore)) }),
75
+ ...(notBefore && { nbfDate: (0, helpers_1._secToDate)(iat + (0, helpers_1._toSeconds)((0, parse_1.parseMSec)(notBefore))) }),
76
+ ...(audience && { aud: audience }),
77
+ ...(subject && { sub: subject }),
78
+ ...(issuer && { iss: issuer }),
79
+ ...payload,
80
+ };
81
+ const header = { alg: 'HS256', typ: 'SIGNET+JWT' };
82
+ const headerJson = (0, index_1.stableStringify)(header);
83
+ const payloadJson = (0, index_1.stableStringify)($payload);
84
+ const headerB = (0, utils_1.utf8ToBytes)(headerJson);
85
+ const payloadB = (0, utils_1.utf8ToBytes)(payloadJson);
86
+ const signingInput = `${(0, utils_1.bytesToBase64)(headerB)}.${(0, utils_1.bytesToBase64)(payloadB)}`;
87
+ const mac = (0, utils_1.hmacSha256)(this.#secretBytes, (0, utils_1.utf8ToBytes)(signingInput));
88
+ const signature = (0, utils_1.bytesToBase64)(mac);
89
+ return `${signingInput}.${signature}`;
90
+ }
91
+ decode(token) {
92
+ return this.#decode(token);
93
+ }
94
+ hasExpired(token) {
95
+ const { exp } = this.#decode(token).payload;
96
+ return exp ? (0, helpers_1._toSeconds)(Date.now()) > exp : false;
97
+ }
98
+ isTooEarly(token) {
99
+ const { nbf } = this.#decode(token).payload;
100
+ return nbf ? (0, helpers_1._toSeconds)(Date.now()) < nbf : false;
101
+ }
102
+ isInvalidIssuer(token, expected) {
103
+ if (!expected)
104
+ return false;
105
+ const { iss } = this.#decode(token).payload;
106
+ return iss ? iss !== expected : false;
107
+ }
108
+ isInvalidAudience(token, expected) {
109
+ if (!expected)
110
+ return false;
111
+ const { aud } = this.#decode(token).payload;
112
+ if (!aud)
113
+ return false;
114
+ const payloadAud = Array.isArray(aud) ? aud : [aud];
115
+ const expectedAud = Array.isArray(expected) ? expected : [expected];
116
+ return payloadAud.some((tokenAud) => expectedAud.includes(tokenAud));
117
+ }
118
+ isInvalidSubject(token, expected) {
119
+ if (!expected)
120
+ return false;
121
+ const { sub } = this.#decode(token).payload;
122
+ return sub ? sub !== expected : false;
123
+ }
124
+ verify(token, options) {
125
+ try {
126
+ const { signature, signingInput, payload } = this.#decode(token);
127
+ const { audience, issuer, subject } = options || {};
128
+ const expectedMac = (0, utils_1.hmacSha256)(this.#secretBytes, (0, utils_1.utf8ToBytes)(signingInput));
129
+ const expectedSig = (0, utils_1.bytesToBase64)(expectedMac);
130
+ if (!(0, helpers_1._constantTimeEquals)(signature, expectedSig)) {
131
+ throw new Error('Invalid or tampered signature!');
132
+ }
133
+ if (this.hasExpired(token)) {
134
+ throw new Error('Token has expired!');
135
+ }
136
+ if (this.isTooEarly(token)) {
137
+ throw new Error('Token is not active yet!');
138
+ }
139
+ if (this.isInvalidIssuer(token, issuer)) {
140
+ throw new Error('Invalid token issuer!');
141
+ }
142
+ if (this.isInvalidAudience(token, audience)) {
143
+ throw new Error('Invalid token audience(s!');
144
+ }
145
+ if (this.isInvalidSubject(token, subject)) {
146
+ throw new Error('Invalid token subject!');
147
+ }
148
+ return { isValid: true, payload };
149
+ }
150
+ catch (e) {
151
+ return {
152
+ isValid: false,
153
+ error: e instanceof Error ? e.message : String(e),
154
+ };
155
+ }
156
+ }
157
+ verifyOrThrow(token, options) {
158
+ const res = this.verify(token, options);
159
+ if (!res.isValid) {
160
+ throw new Error(res.error || 'Invalid, malformed or expired token!');
161
+ }
162
+ return res;
163
+ }
164
+ decodePayload(token) {
165
+ return this.#decode(token).payload;
166
+ }
167
+ }
168
+ exports.Signet = Signet;
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.md5 = md5;
4
+ exports.sha1 = sha1;
5
+ exports.sha256 = sha256;
6
+ const helpers_1 = require("./helpers");
7
+ const utils_1 = require("./utils");
8
+ function md5(str) {
9
+ const state = [1732584193, -271733879, -1732584194, 271733878];
10
+ const len = str.length;
11
+ let i;
12
+ for (i = 64; i <= len; i += 64) {
13
+ (0, helpers_1._md5cycle)(state, (0, helpers_1._stringToNumbers)(str.substring(i - 64, i)));
14
+ }
15
+ const $str = str.substring(i - 64);
16
+ const tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
17
+ for (i = 0; i < $str.length; i++) {
18
+ tail[i >> 2] |= $str.charCodeAt(i) << (i % 4 << 3);
19
+ }
20
+ tail[i >> 2] |= 0x80 << (i % 4 << 3);
21
+ if (i > 55) {
22
+ (0, helpers_1._md5cycle)(state, tail);
23
+ for (let j = 0; j < 16; j++) {
24
+ tail[j] = 0;
25
+ }
26
+ }
27
+ tail[14] = len * 8;
28
+ (0, helpers_1._md5cycle)(state, tail);
29
+ return state.map(helpers_1._numToHex).join('');
30
+ }
31
+ function sha1(msg) {
32
+ const K = [0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6];
33
+ const utf8 = (0, utils_1.utf8ToBytes)(msg);
34
+ const rotl = (n, bits) => (n << bits) | (n >>> (32 - bits));
35
+ const toHex = (n) => (n >>> 0).toString(16).padStart(8, '0');
36
+ const len = utf8.length;
37
+ const padBytes = (len + 9) % 64 ? 64 - ((len + 9) % 64) : 0;
38
+ const total = len + 1 + padBytes + 8;
39
+ const words = new Uint32Array(total >>> 2);
40
+ for (let i = 0; i < utf8.length; i++) {
41
+ words[i >> 2] |= utf8[i] << (24 - (i % 4) * 8);
42
+ }
43
+ words[utf8.length >> 2] |= 0x80 << (24 - (utf8.length % 4) * 8);
44
+ words[words.length - 1] = utf8.length * 8;
45
+ const h = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0];
46
+ const W = new Uint32Array(80);
47
+ for (let i = 0; i < words.length; i += 16) {
48
+ for (let j = 0; j < 16; j++)
49
+ W[j] = words[i + j] | 0;
50
+ for (let j = 16; j < 80; j++) {
51
+ W[j] = rotl(W[j - 3] ^ W[j - 8] ^ W[j - 14] ^ W[j - 16], 1);
52
+ }
53
+ let a = h[0], b = h[1], c = h[2], d = h[3], e = h[4];
54
+ for (let j = 0; j < 80; j++) {
55
+ let f, k;
56
+ if (j < 20) {
57
+ f = (b & c) | (~b & d);
58
+ k = K[0];
59
+ }
60
+ else if (j < 40) {
61
+ f = b ^ c ^ d;
62
+ k = K[1];
63
+ }
64
+ else if (j < 60) {
65
+ f = (b & c) | (b & d) | (c & d);
66
+ k = K[2];
67
+ }
68
+ else {
69
+ f = b ^ c ^ d;
70
+ k = K[3];
71
+ }
72
+ const temp = (rotl(a, 5) + f + e + k + W[j]) | 0;
73
+ e = d;
74
+ d = c;
75
+ c = rotl(b, 30);
76
+ b = a;
77
+ a = temp;
78
+ }
79
+ h[0] = (h[0] + a) | 0;
80
+ h[1] = (h[1] + b) | 0;
81
+ h[2] = (h[2] + c) | 0;
82
+ h[3] = (h[3] + d) | 0;
83
+ h[4] = (h[4] + e) | 0;
84
+ }
85
+ return h.map(toHex).join('');
86
+ }
87
+ function sha256(msg) {
88
+ return (0, utils_1.bytesToHex)((0, utils_1.sha256Bytes)((0, utils_1.utf8ToBytes)(msg)));
89
+ }