js-confuser 1.5.9 → 1.7.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 (143) hide show
  1. package/.github/workflows/node.js.yml +2 -2
  2. package/CHANGELOG.md +55 -0
  3. package/README.md +346 -165
  4. package/dist/constants.js +6 -2
  5. package/dist/index.js +9 -21
  6. package/dist/obfuscator.js +19 -31
  7. package/dist/options.js +5 -5
  8. package/dist/order.js +1 -3
  9. package/dist/presets.js +6 -7
  10. package/dist/probability.js +2 -4
  11. package/dist/templates/bufferToString.js +13 -0
  12. package/dist/templates/crash.js +3 -3
  13. package/dist/templates/es5.js +18 -0
  14. package/dist/templates/functionLength.js +16 -0
  15. package/dist/transforms/calculator.js +77 -21
  16. package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +980 -367
  17. package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +4 -1
  18. package/dist/transforms/controlFlowFlattening/switchCaseObfuscation.js +25 -26
  19. package/dist/transforms/deadCode.js +33 -25
  20. package/dist/transforms/dispatcher.js +8 -4
  21. package/dist/transforms/es5/antiDestructuring.js +2 -0
  22. package/dist/transforms/es5/es5.js +31 -34
  23. package/dist/transforms/extraction/duplicateLiteralsRemoval.js +92 -58
  24. package/dist/transforms/finalizer.js +82 -0
  25. package/dist/transforms/flatten.js +229 -148
  26. package/dist/transforms/identifier/globalAnalysis.js +88 -0
  27. package/dist/transforms/identifier/globalConcealing.js +10 -83
  28. package/dist/transforms/identifier/movedDeclarations.js +35 -88
  29. package/dist/transforms/identifier/renameVariables.js +124 -59
  30. package/dist/transforms/identifier/variableAnalysis.js +58 -62
  31. package/dist/transforms/lock/lock.js +0 -37
  32. package/dist/transforms/minify.js +60 -57
  33. package/dist/transforms/opaquePredicates.js +1 -1
  34. package/dist/transforms/preparation/preparation.js +2 -2
  35. package/dist/transforms/preparation.js +231 -0
  36. package/dist/transforms/renameLabels.js +1 -1
  37. package/dist/transforms/rgf.js +139 -247
  38. package/dist/transforms/stack.js +128 -26
  39. package/dist/transforms/string/encoding.js +150 -179
  40. package/dist/transforms/string/stringCompression.js +14 -15
  41. package/dist/transforms/string/stringConcealing.js +25 -8
  42. package/dist/transforms/string/stringEncoding.js +13 -24
  43. package/dist/transforms/transform.js +12 -19
  44. package/dist/traverse.js +24 -10
  45. package/dist/util/gen.js +17 -1
  46. package/dist/util/identifiers.js +37 -3
  47. package/dist/util/insert.js +35 -4
  48. package/dist/util/random.js +15 -0
  49. package/docs/ControlFlowFlattening.md +595 -0
  50. package/{Countermeasures.md → docs/Countermeasures.md} +1 -15
  51. package/{Integrity.md → docs/Integrity.md} +2 -2
  52. package/docs/RGF.md +419 -0
  53. package/package.json +5 -5
  54. package/src/constants.ts +3 -0
  55. package/src/index.ts +2 -2
  56. package/src/obfuscator.ts +19 -31
  57. package/src/options.ts +14 -103
  58. package/src/order.ts +1 -5
  59. package/src/presets.ts +6 -7
  60. package/src/probability.ts +2 -3
  61. package/src/templates/bufferToString.ts +68 -0
  62. package/src/templates/crash.ts +15 -19
  63. package/src/templates/es5.ts +131 -0
  64. package/src/templates/functionLength.ts +14 -0
  65. package/src/transforms/calculator.ts +122 -59
  66. package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +1583 -571
  67. package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +4 -1
  68. package/src/transforms/deadCode.ts +383 -26
  69. package/src/transforms/dispatcher.ts +9 -4
  70. package/src/transforms/es5/antiDestructuring.ts +2 -0
  71. package/src/transforms/es5/es5.ts +32 -77
  72. package/src/transforms/extraction/duplicateLiteralsRemoval.ts +133 -129
  73. package/src/transforms/{hexadecimalNumbers.ts → finalizer.ts} +29 -13
  74. package/src/transforms/flatten.ts +357 -300
  75. package/src/transforms/identifier/globalAnalysis.ts +85 -0
  76. package/src/transforms/identifier/globalConcealing.ts +14 -103
  77. package/src/transforms/identifier/movedDeclarations.ts +49 -102
  78. package/src/transforms/identifier/renameVariables.ts +149 -78
  79. package/src/transforms/identifier/variableAnalysis.ts +66 -73
  80. package/src/transforms/lock/lock.ts +1 -42
  81. package/src/transforms/minify.ts +91 -75
  82. package/src/transforms/opaquePredicates.ts +2 -2
  83. package/src/transforms/preparation.ts +238 -0
  84. package/src/transforms/renameLabels.ts +2 -2
  85. package/src/transforms/rgf.ts +213 -405
  86. package/src/transforms/stack.ts +156 -36
  87. package/src/transforms/string/encoding.ts +115 -212
  88. package/src/transforms/string/stringCompression.ts +27 -18
  89. package/src/transforms/string/stringConcealing.ts +39 -9
  90. package/src/transforms/string/stringEncoding.ts +18 -18
  91. package/src/transforms/transform.ts +21 -23
  92. package/src/traverse.ts +23 -4
  93. package/src/types.ts +2 -1
  94. package/src/util/gen.ts +28 -3
  95. package/src/util/identifiers.ts +43 -2
  96. package/src/util/insert.ts +38 -3
  97. package/src/util/random.ts +13 -0
  98. package/test/code/Cash.test.ts +1 -1
  99. package/test/code/Dynamic.test.ts +12 -10
  100. package/test/code/ES6.src.js +146 -0
  101. package/test/code/ES6.test.ts +28 -2
  102. package/test/index.test.ts +2 -1
  103. package/test/probability.test.ts +44 -0
  104. package/test/templates/template.test.ts +1 -1
  105. package/test/transforms/antiTooling.test.ts +22 -0
  106. package/test/transforms/calculator.test.ts +40 -0
  107. package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +702 -160
  108. package/test/transforms/controlFlowFlattening/expressionObfuscation.test.ts +173 -0
  109. package/test/transforms/deadCode.test.ts +66 -15
  110. package/test/transforms/dispatcher.test.ts +20 -1
  111. package/test/transforms/es5/antiDestructuring.test.ts +16 -0
  112. package/test/transforms/flatten.test.ts +399 -86
  113. package/test/transforms/identifier/movedDeclarations.test.ts +63 -8
  114. package/test/transforms/identifier/renameVariables.test.ts +119 -0
  115. package/test/transforms/lock/antiDebug.test.ts +2 -2
  116. package/test/transforms/lock/lock.test.ts +1 -48
  117. package/test/transforms/minify.test.ts +104 -0
  118. package/test/transforms/preparation.test.ts +157 -0
  119. package/test/transforms/rgf.test.ts +261 -381
  120. package/test/transforms/stack.test.ts +143 -21
  121. package/test/transforms/string/stringCompression.test.ts +39 -0
  122. package/test/transforms/string/stringConcealing.test.ts +82 -0
  123. package/test/transforms/string/stringEncoding.test.ts +53 -2
  124. package/test/transforms/transform.test.ts +66 -0
  125. package/test/traverse.test.ts +139 -0
  126. package/test/util/identifiers.test.ts +113 -1
  127. package/test/util/insert.test.ts +57 -3
  128. package/src/transforms/controlFlowFlattening/choiceFlowObfuscation.ts +0 -87
  129. package/src/transforms/controlFlowFlattening/controlFlowObfuscation.ts +0 -203
  130. package/src/transforms/controlFlowFlattening/switchCaseObfuscation.ts +0 -130
  131. package/src/transforms/eval.ts +0 -89
  132. package/src/transforms/hideInitializingCode.ts +0 -432
  133. package/src/transforms/identifier/nameRecycling.ts +0 -280
  134. package/src/transforms/label.ts +0 -64
  135. package/src/transforms/preparation/nameConflicts.ts +0 -102
  136. package/src/transforms/preparation/preparation.ts +0 -176
  137. package/test/transforms/controlFlowFlattening/controlFlowObfuscation.test.ts +0 -101
  138. package/test/transforms/controlFlowFlattening/switchCaseObfuscation.test.ts +0 -120
  139. package/test/transforms/eval.test.ts +0 -131
  140. package/test/transforms/hideInitializingCode.test.ts +0 -336
  141. package/test/transforms/identifier/nameRecycling.test.ts +0 -205
  142. package/test/transforms/preparation/nameConflicts.test.ts +0 -52
  143. package/test/transforms/preparation/preparation.test.ts +0 -62
@@ -1,6 +1,4 @@
1
1
  import { ok } from "assert";
2
- import { stringify } from "querystring";
3
- import { reservedIdentifiers } from "../constants";
4
2
  import { ObfuscateOrder } from "../order";
5
3
  import { ComputeProbabilityMap } from "../probability";
6
4
  import Template from "../templates/template";
@@ -8,11 +6,11 @@ import { walk } from "../traverse";
8
6
  import {
9
7
  AssignmentExpression,
10
8
  BinaryExpression,
9
+ CallExpression,
11
10
  ExpressionStatement,
12
11
  Identifier,
13
12
  IfStatement,
14
13
  Literal,
15
- Location,
16
14
  MemberExpression,
17
15
  Node,
18
16
  RestElement,
@@ -21,24 +19,29 @@ import {
21
19
  } from "../util/gen";
22
20
  import { getIdentifierInfo } from "../util/identifiers";
23
21
  import {
22
+ computeFunctionLength,
23
+ getBlockBody,
24
24
  getDefiningContext,
25
25
  getReferencingContexts,
26
- getVarContext,
27
26
  isForInitialize,
28
27
  isFunction,
29
28
  isVarContext,
30
29
  prepend,
31
30
  } from "../util/insert";
32
- import { choice, getRandomInteger, getRandomString } from "../util/random";
31
+ import { chance, choice, getRandomInteger } from "../util/random";
33
32
  import Transform from "./transform";
33
+ import { noRenameVariablePrefix } from "../constants";
34
+ import { FunctionLengthTemplate } from "../templates/functionLength";
34
35
 
35
36
  export default class Stack extends Transform {
36
- made: number;
37
+ mangledExpressionsMade: number;
38
+
39
+ functionLengthName: string;
37
40
 
38
41
  constructor(o) {
39
42
  super(o, ObfuscateOrder.Stack);
40
43
 
41
- this.made = 0;
44
+ this.mangledExpressionsMade = 0;
42
45
  }
43
46
 
44
47
  match(object: Node, parents: Node[]) {
@@ -66,13 +69,42 @@ export default class Stack extends Transform {
66
69
  }
67
70
  }
68
71
 
72
+ // Don't apply to functions with 'use strict' directive
73
+ if (getBlockBody(object.body)[0]?.directive) {
74
+ return;
75
+ }
76
+
77
+ if (!ComputeProbabilityMap(this.options.stack)) {
78
+ return;
79
+ }
80
+
69
81
  var defined = new Set<string>();
70
82
  var referenced = new Set<string>();
71
83
  var illegal = new Set<string>();
72
84
 
85
+ /**
86
+ * Maps old names to new indices
87
+ */
73
88
  var subscripts = new Map<string, string>();
74
89
  var deadValues = Object.create(null);
75
90
 
91
+ var propertyGen = this.getGenerator();
92
+
93
+ function isTransformableFunction(functionNode: Node) {
94
+ if (functionNode.$requiresEval) return false;
95
+
96
+ // Check for 'this'
97
+ var isIllegal = false;
98
+ walk(functionNode.body, [], (o, p) => {
99
+ if (o.type === "ThisExpression") {
100
+ isIllegal = true;
101
+ return "EXIT";
102
+ }
103
+ });
104
+
105
+ return !isIllegal;
106
+ }
107
+
76
108
  function setSubscript(string, index) {
77
109
  subscripts.set(string, index + "");
78
110
  }
@@ -85,19 +117,30 @@ export default class Stack extends Transform {
85
117
  });
86
118
 
87
119
  var startingSize = subscripts.size;
120
+ var isIllegal = false;
88
121
 
89
122
  walk(object.body, [object, ...parents], (o, p) => {
123
+ if (o.type === "Identifier" && o.name === "arguments") {
124
+ isIllegal = true;
125
+ return "EXIT";
126
+ }
127
+
90
128
  if (o.type == "Identifier") {
91
129
  var info = getIdentifierInfo(o, p);
92
- if (!info.spec.isReferenced) {
130
+ if (!info.spec.isReferenced || info.spec.isExported) {
93
131
  return;
94
132
  }
133
+
95
134
  var c = info.spec.isDefined
96
135
  ? getDefiningContext(o, p)
97
136
  : getReferencingContexts(o, p).find((x) => isVarContext(x));
98
137
 
99
138
  if (c !== object) {
100
- this.log(o.name + " is illegal due to different context");
139
+ // this.log(o.name + " is illegal due to different context");
140
+ illegal.add(o.name);
141
+ }
142
+
143
+ if (o.name.startsWith(noRenameVariablePrefix)) {
101
144
  illegal.add(o.name);
102
145
  }
103
146
 
@@ -106,9 +149,9 @@ export default class Stack extends Transform {
106
149
  info.isFunctionParameter ||
107
150
  isForInitialize(o, p)
108
151
  ) {
109
- this.log(
110
- o.name + " is illegal due to clause parameter/function parameter"
111
- );
152
+ // this.log(
153
+ // o.name + " is illegal due to clause parameter/function parameter"
154
+ // );
112
155
  illegal.add(o.name);
113
156
  }
114
157
  if (o.hidden) {
@@ -121,27 +164,60 @@ export default class Stack extends Transform {
121
164
  }
122
165
 
123
166
  if (info.isFunctionDeclaration) {
124
- if (p[0] !== object.body.body[0]) {
167
+ ok(p[0].type === "FunctionDeclaration");
168
+ if (
169
+ p[0] !== object.body.body[0] ||
170
+ !isTransformableFunction(p[0])
171
+ ) {
125
172
  illegal.add(o.name);
126
173
  }
127
174
  }
128
175
 
129
- setSubscript(o.name, subscripts.size);
176
+ // The new accessors will either be numbered: [index] or as a string .string
177
+ var newSubscript = choice([
178
+ subscripts.size,
179
+ propertyGen.generate(),
180
+ ]);
181
+
182
+ setSubscript(o.name, newSubscript);
130
183
  defined.add(o.name);
131
184
 
185
+ // Stack can only process single VariableDeclarations
132
186
  var varIndex = p.findIndex((x) => x.type == "VariableDeclaration");
133
- if (
134
- varIndex !== -1 &&
135
- (varIndex !== 2 || p[varIndex].declarations.length > 1)
136
- ) {
137
- illegal.add(o.name);
187
+
188
+ if (varIndex !== -1) {
189
+ // Invalid 'id' property (must be Identifier)
190
+ if (varIndex !== 2) {
191
+ illegal.add(o.name);
192
+ } else if (p[varIndex].declarations.length > 1) {
193
+ illegal.add(o.name);
194
+ } else {
195
+ var value = p[varIndex].declarations[0].init;
196
+ if (value && !isTransformableFunction(value)) {
197
+ illegal.add(o.name);
198
+ }
199
+ }
138
200
  }
139
201
  } else if (info.spec.isReferenced) {
202
+ if (info.spec.isModified) {
203
+ var assignmentIndex = p.findIndex(
204
+ (x) => x.type === "AssignmentExpression"
205
+ );
206
+ if (assignmentIndex !== -1) {
207
+ var value = p[assignmentIndex].right;
208
+ if (value && !isTransformableFunction(value)) {
209
+ illegal.add(o.name);
210
+ }
211
+ }
212
+ }
213
+
140
214
  referenced.add(o.name);
141
215
  }
142
216
  }
143
217
  });
144
218
 
219
+ if (isIllegal) return;
220
+
145
221
  illegal.forEach((name) => {
146
222
  defined.delete(name);
147
223
  referenced.delete(name);
@@ -162,16 +238,17 @@ export default class Stack extends Transform {
162
238
  return;
163
239
  }
164
240
 
165
- function numberLiteral(number, depth = 0) {
241
+ const numberLiteral = (number: number | string, depth = 0): Node => {
166
242
  ok(number === number);
167
243
  if (
168
244
  typeof number !== "number" ||
169
245
  !Object.keys(deadValues).length ||
170
- depth > 5 ||
171
- Math.random() > (depth == 0 ? 0.9 : 0.8 / (depth * 2))
246
+ depth > 4 ||
247
+ chance(75 + depth * 15 + this.mangledExpressionsMade / 25)
172
248
  ) {
173
249
  return Literal(number);
174
250
  }
251
+ this.mangledExpressionsMade++;
175
252
 
176
253
  var opposingIndex = choice(Object.keys(deadValues));
177
254
  if (typeof opposingIndex === "undefined") {
@@ -195,7 +272,7 @@ export default class Stack extends Transform {
195
272
  ),
196
273
  numberLiteral(actualValue - number, depth + 1)
197
274
  );
198
- }
275
+ };
199
276
 
200
277
  function getMemberExpression(index) {
201
278
  ok(typeof index === "string", typeof index);
@@ -206,8 +283,7 @@ export default class Stack extends Transform {
206
283
  );
207
284
  }
208
285
 
209
- var stackName = this.getPlaceholder();
210
- var made = 1;
286
+ var stackName = this.getPlaceholder() + "_stack";
211
287
 
212
288
  const scan = (o, p) => {
213
289
  if (o.type == "Identifier") {
@@ -289,10 +365,9 @@ export default class Stack extends Transform {
289
365
  typeof o.value === "number" &&
290
366
  Math.floor(o.value) === o.value &&
291
367
  Math.abs(o.value) < 100_000 &&
292
- Math.random() < 4 / made &&
293
- p.find((x) => isFunction(x)) === object
368
+ p.find((x) => isFunction(x)) === object &&
369
+ chance(50)
294
370
  ) {
295
- made++;
296
371
  return () => {
297
372
  this.replaceIdentifierOrLiteral(o, numberLiteral(o.value, 0), p);
298
373
  };
@@ -304,10 +379,10 @@ export default class Stack extends Transform {
304
379
  object.body.body.forEach((stmt, index) => {
305
380
  var isFirst = index == 0;
306
381
 
307
- if (isFirst || Math.random() < 0.9 / index) {
382
+ if (isFirst || chance(50 - index * 10)) {
308
383
  var exprs = [];
309
384
 
310
- var changes = getRandomInteger(isFirst ? 2 : 1, isFirst ? 3 : 2);
385
+ var changes = getRandomInteger(1, 3);
311
386
 
312
387
  for (var i = 0; i < changes; i++) {
313
388
  var expr;
@@ -320,8 +395,10 @@ export default class Stack extends Transform {
320
395
  var newIndex;
321
396
  var i = 0;
322
397
  do {
323
- newIndex =
324
- getRandomInteger(0, 250 + subscripts.size + i * 1000) + "";
398
+ newIndex = choice([
399
+ propertyGen.generate(),
400
+ getRandomInteger(0, 250 + subscripts.size + i * 1000) + "",
401
+ ]);
325
402
  i++;
326
403
  } while (valueSet.has(newIndex));
327
404
 
@@ -344,10 +421,10 @@ export default class Stack extends Transform {
344
421
  break;
345
422
 
346
423
  case "deadValue":
347
- var rand = getRandomInteger(-250, 250);
424
+ var rand = getRandomInteger(-150, 150);
348
425
 
349
426
  // modify an already existing dead value index
350
- if (Math.random() > 0.5) {
427
+ if (chance(50)) {
351
428
  var alreadyExisting = choice(Object.keys(deadValues));
352
429
 
353
430
  if (typeof alreadyExisting === "string") {
@@ -361,7 +438,6 @@ export default class Stack extends Transform {
361
438
  numberLiteral(rand)
362
439
  );
363
440
 
364
- ok(!subscripts.has(newIndex));
365
441
  deadValues[newIndex] = rand;
366
442
  break;
367
443
  }
@@ -409,14 +485,58 @@ export default class Stack extends Transform {
409
485
  object.body.body.splice(parseInt(index) + i, 0, rotateNodes[index]);
410
486
  });
411
487
 
488
+ // Preserve function.length property
489
+ var originalFunctionLength = computeFunctionLength(object.params);
490
+
412
491
  // Set the params for this function to be the stack array
413
492
  object.params = [RestElement(Identifier(stackName))];
414
493
 
415
494
  // Ensure the array is correct length
416
495
  prepend(
417
496
  object.body,
418
- Template(`${stackName}.length = ${startingSize}`).single()
497
+ Template(`${stackName}["length"] = ${startingSize}`).single()
419
498
  );
499
+
500
+ if (originalFunctionLength !== 0) {
501
+ if (!this.functionLengthName) {
502
+ this.functionLengthName = this.getPlaceholder();
503
+ prepend(
504
+ parents[parents.length - 1] || object,
505
+ FunctionLengthTemplate.single({ name: this.functionLengthName })
506
+ );
507
+ }
508
+
509
+ if (object.type === "FunctionDeclaration") {
510
+ var body = parents[0];
511
+ if (Array.isArray(body)) {
512
+ var index = body.indexOf(object);
513
+
514
+ body.splice(
515
+ index,
516
+ 0,
517
+ ExpressionStatement(
518
+ CallExpression(Identifier(this.functionLengthName), [
519
+ Identifier(object.id.name),
520
+ Literal(originalFunctionLength),
521
+ ])
522
+ )
523
+ );
524
+ }
525
+ } else {
526
+ ok(
527
+ object.type === "FunctionExpression" ||
528
+ object.type === "ArrowFunctionExpression"
529
+ );
530
+
531
+ this.replace(
532
+ object,
533
+ CallExpression(Identifier(this.functionLengthName), [
534
+ { ...object },
535
+ Literal(originalFunctionLength),
536
+ ])
537
+ );
538
+ }
539
+ }
420
540
  };
421
541
  }
422
542
  }
@@ -7,7 +7,120 @@ const Encoding: {
7
7
  template: ReturnType<typeof Template>;
8
8
  };
9
9
  } = {
10
- ascii85: {
10
+ base91: {
11
+ encode(str) {
12
+ const table =
13
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,./:;<=>?@[]^_`{|}~"';
14
+
15
+ const raw = Buffer.from(str, "utf-8");
16
+ const len = raw.length;
17
+ let ret = "";
18
+
19
+ let n = 0;
20
+ let b = 0;
21
+
22
+ for (let i = 0; i < len; i++) {
23
+ b |= raw[i] << n;
24
+ n += 8;
25
+
26
+ if (n > 13) {
27
+ let v = b & 8191;
28
+ if (v > 88) {
29
+ b >>= 13;
30
+ n -= 13;
31
+ } else {
32
+ v = b & 16383;
33
+ b >>= 14;
34
+ n -= 14;
35
+ }
36
+ ret += table[v % 91] + table[(v / 91) | 0];
37
+ }
38
+ }
39
+
40
+ if (n) {
41
+ ret += table[b % 91];
42
+ if (n > 7 || b > 90) ret += table[(b / 91) | 0];
43
+ }
44
+
45
+ return ret;
46
+ },
47
+ decode(str) {
48
+ const table =
49
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,./:;<=>?@[]^_`{|}~"';
50
+
51
+ const raw = "" + (str || "");
52
+ const len = raw.length;
53
+ const ret = [];
54
+
55
+ let b = 0;
56
+ let n = 0;
57
+ let v = -1;
58
+
59
+ for (let i = 0; i < len; i++) {
60
+ const p = table.indexOf(raw[i]);
61
+ if (p === -1) continue;
62
+ if (v < 0) {
63
+ v = p;
64
+ } else {
65
+ v += p * 91;
66
+ b |= v << n;
67
+ n += (v & 8191) > 88 ? 13 : 14;
68
+ do {
69
+ ret.push(b & 0xff);
70
+ b >>= 8;
71
+ n -= 8;
72
+ } while (n > 7);
73
+ v = -1;
74
+ }
75
+ }
76
+
77
+ if (v > -1) {
78
+ ret.push((b | (v << n)) & 0xff);
79
+ }
80
+
81
+ return Buffer.from(ret).toString("utf-8");
82
+ },
83
+ template: Template(`
84
+ function {name}(str){
85
+ const table =
86
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,./:;<=>?@[]^_\`{|}~"';
87
+
88
+ const raw = "" + (str || "");
89
+ const len = raw.length;
90
+ const ret = [];
91
+
92
+ let b = 0;
93
+ let n = 0;
94
+ let v = -1;
95
+
96
+ for (let i = 0; i < len; i++) {
97
+ const p = table.indexOf(raw[i]);
98
+ if (p === -1) continue;
99
+ if (v < 0) {
100
+ v = p;
101
+ } else {
102
+ v += p * 91;
103
+ b |= v << n;
104
+ n += (v & 8191) > 88 ? 13 : 14;
105
+ do {
106
+ ret.push(b & 0xff);
107
+ b >>= 8;
108
+ n -= 8;
109
+ } while (n > 7);
110
+ v = -1;
111
+ }
112
+ }
113
+
114
+ if (v > -1) {
115
+ ret.push((b | (v << n)) & 0xff);
116
+ }
117
+
118
+ return {bufferToString}(ret);
119
+ }
120
+ `),
121
+ },
122
+
123
+ /* ascii85: { This implementation is flaky and causes decoding errors
11
124
  encode(a) {
12
125
  var b, c, d, e, f, g, h, i, j, k;
13
126
  // @ts-ignore
@@ -94,217 +207,7 @@ const Encoding: {
94
207
  }(e, c[l]), h[LL[0]][LL[1]](h, e);
95
208
  }
96
209
  `),
97
- },
98
-
99
- base32: {
100
- encode: function (s) {
101
- var a = "!\"#$%&'()*+,-./0123456789:;<=>?@";
102
- var len = s.length;
103
- var o = "";
104
- var w,
105
- c,
106
- r = 0,
107
- sh = 0,
108
- i;
109
- for (i = 0; i < len; i += 5) {
110
- // mask top 5 bits
111
- c = s.charCodeAt(i);
112
- w = 0xf8 & c;
113
- o += a.charAt(w >> 3);
114
- r = 0x07 & c;
115
- sh = 2;
116
-
117
- if (i + 1 < len) {
118
- c = s.charCodeAt(i + 1);
119
- // mask top 2 bits
120
- w = 0xc0 & c;
121
- o += a.charAt((r << 2) + (w >> 6));
122
- o += a.charAt((0x3e & c) >> 1);
123
- r = c & 0x01;
124
- sh = 4;
125
- }
126
-
127
- if (i + 2 < len) {
128
- c = s.charCodeAt(i + 2);
129
- // mask top 4 bits
130
- w = 0xf0 & c;
131
- o += a.charAt((r << 4) + (w >> 4));
132
- r = 0x0f & c;
133
- sh = 1;
134
- }
135
-
136
- if (i + 3 < len) {
137
- c = s.charCodeAt(i + 3);
138
- // mask top 1 bit
139
- w = 0x80 & c;
140
- o += a.charAt((r << 1) + (w >> 7));
141
- o += a.charAt((0x7c & c) >> 2);
142
- r = 0x03 & c;
143
- sh = 3;
144
- }
145
-
146
- if (i + 4 < len) {
147
- c = s.charCodeAt(i + 4);
148
- // mask top 3 bits
149
- w = 0xe0 & c;
150
- o += a.charAt((r << 3) + (w >> 5));
151
- o += a.charAt(0x1f & c);
152
- r = 0;
153
- sh = 0;
154
- }
155
- }
156
- // Calculate length of pad by getting the
157
- // number of words to reach an 8th octet.
158
- if (r != 0) {
159
- o += a.charAt(r << sh);
160
- }
161
- return o;
162
- },
163
- decode: function (s) {
164
- var v,
165
- x,
166
- bits = 0,
167
- o = "",
168
- len = s.length,
169
- d = String,
170
- e = "charCodeAt",
171
- f = "fromCharCode",
172
- i;
173
-
174
- for (i = 0; i < len; i += 1) {
175
- (v = s[e](i) - 33),
176
- v >= 0 && v < 32
177
- ? ((bits += ((x = (x << 5) | v), 5)),
178
- bits >= 8
179
- ? (bits -= ((o += d[f]((x >> (bits - 8)) & 0xff)), 8))
180
- : 0)
181
- : 0;
182
- }
183
- return o;
184
- },
185
- template: Template(`
186
- function {name}(s) {
187
- var v,
188
- x,
189
- b = 0,
190
- o = "",
191
- len = s.length,
192
- d = String,
193
- e = "charCodeAt",
194
- f = "fromCharCode", i;
195
-
196
- for (i = 0; i < len; i += 1) {
197
- (v = s[e](i) - 33),
198
- v >= 0 && v < 32
199
- ? ((b += ((x = (x << 5) | v), 5)),
200
- b >= 8
201
- ? (b -= ((o += d[f]((x >> (b - 8)) & 0xff)), 8))
202
- : 0)
203
- : 0;
204
- }
205
- return o;
206
- }
207
- `),
208
- },
209
-
210
- hexTable: {
211
- encode: function (str) {
212
- var output = "";
213
-
214
- for (var j = 0; j < str.length; j += 3) {
215
- var chunk = str.substring(j, j + 3);
216
- if (!chunk) {
217
- continue;
218
- }
219
-
220
- chunk = chunk + "~";
221
-
222
- var uniqueChars = new Set([]);
223
- for (var char of chunk) {
224
- uniqueChars.add(char);
225
- }
226
-
227
- var keys = Array.from(uniqueChars).sort();
228
- var table = {},
229
- i = 0;
230
- for (var key of keys) {
231
- table[key] = i++;
232
- }
233
-
234
- var idx = [];
235
- for (var char of chunk) {
236
- idx.push(table[char]);
237
- }
238
-
239
- var table64 = "0x";
240
- for (var i = keys.length - 1; i >= 0; i--) {
241
- table64 += keys[i].charCodeAt(0).toString(16).toUpperCase();
242
- }
243
-
244
- var idxInt = 0;
245
- for (var i = idx.length - 1; i >= 0; i--) {
246
- idxInt = (idxInt << 3) | idx[i];
247
- }
248
-
249
- var idx64 = "0x" + idxInt.toString(16).toUpperCase();
250
-
251
- // console.log(chunk, table, idx, table64, idx64);
252
-
253
- output += table64 + "," + idx64 + ",";
254
- }
255
-
256
- if (output.endsWith(",")) {
257
- output = output.substring(0, output.length - 1);
258
- }
259
-
260
- return "{" + output + "}";
261
- },
262
-
263
- decode: function (str) {
264
- var output = "";
265
-
266
- str = str.substring(1, str.length - 1);
267
- var chunks = str.split(",");
268
-
269
- for (var i = 0; i < chunks.length; i += 2) {
270
- var arr = [chunks[i], chunks[i + 1]];
271
-
272
- var [table, idx] = arr.map(Number);
273
-
274
- // console.log(table, idx);
275
- while (idx) {
276
- output += String.fromCharCode((table >> (8 * (idx & 7))) & 0xff);
277
- idx >>= 3;
278
- }
279
- }
280
-
281
- return output.replace(/~/g, "");
282
- },
283
-
284
- template: Template(`
285
- function {name}(str){
286
- var output = "";
287
-
288
- str = str.substring(1, str.length - 1);
289
- var chunks = str.split(",");
290
-
291
- for (var i = 0; i < chunks.length; i += 2) {
292
- var arr = [chunks[i], chunks[i + 1]];
293
-
294
- var [table, idx] = arr.map(Number);
295
-
296
- // console.log(table, idx);
297
- while (idx) {
298
- output += String.fromCharCode((table >> (8 * (idx & 7))) & 0xff);
299
- idx >>= 3;
300
- }
301
- }
302
-
303
- return output.replace(/~/g, "");
304
- }
305
-
306
- `),
307
- },
210
+ }, */
308
211
  };
309
212
 
310
213
  export default Encoding;