js-confuser 1.5.8 → 1.6.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/.github/workflows/node.js.yml +2 -2
- package/CHANGELOG.md +69 -0
- package/README.md +143 -7
- package/dist/index.js +33 -4
- package/dist/obfuscator.js +30 -31
- package/dist/options.js +4 -5
- package/dist/order.js +4 -6
- package/dist/probability.js +2 -4
- package/dist/templates/bufferToString.js +13 -0
- package/dist/templates/crash.js +2 -2
- package/dist/templates/es5.js +18 -0
- package/dist/transforms/antiTooling.js +1 -1
- package/dist/transforms/calculator.js +77 -21
- package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +980 -367
- package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +8 -3
- package/dist/transforms/controlFlowFlattening/switchCaseObfuscation.js +25 -26
- package/dist/transforms/deadCode.js +33 -25
- package/dist/transforms/dispatcher.js +7 -6
- package/dist/transforms/es5/antiClass.js +6 -2
- package/dist/transforms/es5/antiDestructuring.js +3 -1
- package/dist/transforms/es5/es5.js +31 -34
- package/dist/transforms/eval.js +11 -0
- package/dist/transforms/extraction/duplicateLiteralsRemoval.js +8 -5
- package/dist/transforms/extraction/objectExtraction.js +6 -1
- package/dist/transforms/finalizer.js +82 -0
- package/dist/transforms/flatten.js +82 -55
- package/dist/transforms/hexadecimalNumbers.js +34 -9
- package/dist/transforms/identifier/globalAnalysis.js +88 -0
- package/dist/transforms/identifier/globalConcealing.js +10 -83
- package/dist/transforms/identifier/movedDeclarations.js +2 -8
- package/dist/transforms/identifier/renameVariables.js +39 -27
- package/dist/transforms/identifier/variableAnalysis.js +58 -62
- package/dist/transforms/minify.js +80 -61
- package/dist/transforms/opaquePredicates.js +1 -1
- package/dist/transforms/preparation/preparation.js +2 -2
- package/dist/transforms/preparation.js +231 -0
- package/dist/transforms/renameLabels.js +1 -1
- package/dist/transforms/rgf.js +4 -5
- package/dist/transforms/stack.js +87 -26
- package/dist/transforms/string/encoding.js +150 -179
- package/dist/transforms/string/stringCompression.js +14 -15
- package/dist/transforms/string/stringConcealing.js +25 -8
- package/dist/transforms/string/stringEncoding.js +13 -24
- package/dist/transforms/transform.js +11 -18
- package/dist/traverse.js +24 -18
- package/dist/util/compare.js +2 -2
- package/dist/util/gen.js +15 -0
- package/dist/util/insert.js +31 -7
- package/dist/util/random.js +15 -0
- package/package.json +5 -5
- package/src/index.ts +57 -19
- package/src/obfuscator.ts +26 -29
- package/src/options.ts +17 -21
- package/src/order.ts +4 -8
- package/src/probability.ts +2 -3
- package/src/templates/bufferToString.ts +68 -0
- package/src/templates/crash.ts +5 -9
- package/src/templates/es5.ts +131 -0
- package/src/transforms/antiTooling.ts +1 -1
- package/src/transforms/calculator.ts +122 -59
- package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +1583 -571
- package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +18 -3
- package/src/transforms/deadCode.ts +383 -26
- package/src/transforms/dispatcher.ts +8 -6
- package/src/transforms/es5/antiClass.ts +10 -1
- package/src/transforms/es5/antiDestructuring.ts +3 -1
- package/src/transforms/es5/es5.ts +32 -77
- package/src/transforms/eval.ts +18 -0
- package/src/transforms/extraction/duplicateLiteralsRemoval.ts +9 -6
- package/src/transforms/extraction/objectExtraction.ts +12 -5
- package/src/transforms/finalizer.ts +75 -0
- package/src/transforms/flatten.ts +194 -151
- package/src/transforms/identifier/globalAnalysis.ts +85 -0
- package/src/transforms/identifier/globalConcealing.ts +14 -103
- package/src/transforms/identifier/movedDeclarations.ts +4 -11
- package/src/transforms/identifier/renameVariables.ts +37 -30
- package/src/transforms/identifier/variableAnalysis.ts +66 -73
- package/src/transforms/minify.ts +116 -77
- package/src/transforms/opaquePredicates.ts +2 -2
- package/src/transforms/preparation.ts +238 -0
- package/src/transforms/renameLabels.ts +2 -2
- package/src/transforms/rgf.ts +6 -7
- package/src/transforms/stack.ts +97 -37
- package/src/transforms/string/encoding.ts +115 -212
- package/src/transforms/string/stringCompression.ts +27 -18
- package/src/transforms/string/stringConcealing.ts +41 -11
- package/src/transforms/string/stringEncoding.ts +18 -18
- package/src/transforms/transform.ts +15 -21
- package/src/traverse.ts +24 -12
- package/src/types.ts +11 -2
- package/src/util/compare.ts +2 -2
- package/src/util/gen.ts +21 -1
- package/src/util/insert.ts +49 -9
- package/src/util/random.ts +13 -0
- package/test/code/Cash.test.ts +1 -1
- package/test/code/Dynamic.test.ts +12 -10
- package/test/code/ES6.src.js +136 -0
- package/test/code/ES6.test.ts +28 -2
- package/test/code/NewFeatures.test.ts +19 -0
- package/test/index.test.ts +15 -2
- package/test/probability.test.ts +44 -0
- package/test/templates/template.test.ts +1 -1
- package/test/transforms/antiTooling.test.ts +52 -0
- package/test/transforms/calculator.test.ts +40 -0
- package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +713 -149
- package/test/transforms/controlFlowFlattening/expressionObfuscation.test.ts +173 -0
- package/test/transforms/deadCode.test.ts +66 -15
- package/test/transforms/dispatcher.test.ts +44 -1
- package/test/transforms/es5/antiClass.test.ts +33 -0
- package/test/transforms/es5/antiDestructuring.test.ts +16 -0
- package/test/transforms/eval.test.ts +53 -0
- package/test/transforms/extraction/objectExtraction.test.ts +21 -0
- package/test/transforms/flatten.test.ts +195 -3
- package/test/transforms/identifier/movedDeclarations.test.ts +27 -0
- package/test/transforms/identifier/renameVariables.test.ts +108 -0
- package/test/transforms/lock/antiDebug.test.ts +2 -2
- package/test/transforms/minify.test.ts +151 -0
- package/test/transforms/preparation.test.ts +157 -0
- package/test/transforms/rgf.test.ts +56 -29
- package/test/transforms/stack.test.ts +91 -21
- package/test/transforms/string/stringCompression.test.ts +39 -0
- package/test/transforms/string/stringConcealing.test.ts +115 -0
- package/test/transforms/string/stringEncoding.test.ts +53 -2
- package/test/transforms/transform.test.ts +66 -0
- package/test/traverse.test.ts +139 -0
- package/test/util/compare.test.ts +23 -1
- package/src/transforms/controlFlowFlattening/choiceFlowObfuscation.ts +0 -87
- package/src/transforms/controlFlowFlattening/controlFlowObfuscation.ts +0 -203
- package/src/transforms/controlFlowFlattening/switchCaseObfuscation.ts +0 -130
- package/src/transforms/hexadecimalNumbers.ts +0 -31
- package/src/transforms/hideInitializingCode.ts +0 -432
- package/src/transforms/label.ts +0 -64
- package/src/transforms/preparation/nameConflicts.ts +0 -102
- package/src/transforms/preparation/preparation.ts +0 -176
- package/test/transforms/controlFlowFlattening/controlFlowObfuscation.test.ts +0 -101
- package/test/transforms/controlFlowFlattening/switchCaseObfuscation.test.ts +0 -120
- package/test/transforms/hideInitializingCode.test.ts +0 -336
- package/test/transforms/preparation/nameConflicts.test.ts +0 -52
- package/test/transforms/preparation/preparation.test.ts +0 -62
package/src/transforms/stack.ts
CHANGED
|
@@ -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";
|
|
@@ -12,7 +10,6 @@ import {
|
|
|
12
10
|
Identifier,
|
|
13
11
|
IfStatement,
|
|
14
12
|
Literal,
|
|
15
|
-
Location,
|
|
16
13
|
MemberExpression,
|
|
17
14
|
Node,
|
|
18
15
|
RestElement,
|
|
@@ -21,24 +18,24 @@ import {
|
|
|
21
18
|
} from "../util/gen";
|
|
22
19
|
import { getIdentifierInfo } from "../util/identifiers";
|
|
23
20
|
import {
|
|
21
|
+
getBlockBody,
|
|
24
22
|
getDefiningContext,
|
|
25
23
|
getReferencingContexts,
|
|
26
|
-
getVarContext,
|
|
27
24
|
isForInitialize,
|
|
28
25
|
isFunction,
|
|
29
26
|
isVarContext,
|
|
30
27
|
prepend,
|
|
31
28
|
} from "../util/insert";
|
|
32
|
-
import { choice, getRandomInteger
|
|
29
|
+
import { chance, choice, getRandomInteger } from "../util/random";
|
|
33
30
|
import Transform from "./transform";
|
|
34
31
|
|
|
35
32
|
export default class Stack extends Transform {
|
|
36
|
-
|
|
33
|
+
mangledExpressionsMade: number;
|
|
37
34
|
|
|
38
35
|
constructor(o) {
|
|
39
36
|
super(o, ObfuscateOrder.Stack);
|
|
40
37
|
|
|
41
|
-
this.
|
|
38
|
+
this.mangledExpressionsMade = 0;
|
|
42
39
|
}
|
|
43
40
|
|
|
44
41
|
match(object: Node, parents: Node[]) {
|
|
@@ -55,7 +52,9 @@ export default class Stack extends Transform {
|
|
|
55
52
|
return () => {
|
|
56
53
|
// Uncaught SyntaxError: Getter must not have any formal parameters.
|
|
57
54
|
// Uncaught SyntaxError: Setter must have exactly one formal parameter
|
|
58
|
-
var propIndex = parents.findIndex(
|
|
55
|
+
var propIndex = parents.findIndex(
|
|
56
|
+
(x) => x.type === "Property" || x.type === "MethodDefinition"
|
|
57
|
+
);
|
|
59
58
|
if (propIndex !== -1) {
|
|
60
59
|
if (parents[propIndex].value === (parents[propIndex - 1] || object)) {
|
|
61
60
|
if (parents[propIndex].kind !== "init" || parents[propIndex].method) {
|
|
@@ -64,13 +63,42 @@ export default class Stack extends Transform {
|
|
|
64
63
|
}
|
|
65
64
|
}
|
|
66
65
|
|
|
66
|
+
// Don't apply to functions with 'use strict' directive
|
|
67
|
+
if (getBlockBody(object.body)[0]?.directive) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (!ComputeProbabilityMap(this.options.stack)) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
67
75
|
var defined = new Set<string>();
|
|
68
76
|
var referenced = new Set<string>();
|
|
69
77
|
var illegal = new Set<string>();
|
|
70
78
|
|
|
79
|
+
/**
|
|
80
|
+
* Maps old names to new indices
|
|
81
|
+
*/
|
|
71
82
|
var subscripts = new Map<string, string>();
|
|
72
83
|
var deadValues = Object.create(null);
|
|
73
84
|
|
|
85
|
+
var propertyGen = this.getGenerator();
|
|
86
|
+
|
|
87
|
+
function isTransformableFunction(functionNode: Node) {
|
|
88
|
+
if (functionNode.$requiresEval) return false;
|
|
89
|
+
|
|
90
|
+
// Check for 'this'
|
|
91
|
+
var isIllegal = false;
|
|
92
|
+
walk(functionNode.body, [], (o, p) => {
|
|
93
|
+
if (o.type === "ThisExpression") {
|
|
94
|
+
isIllegal = true;
|
|
95
|
+
return "EXIT";
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
return !isIllegal;
|
|
100
|
+
}
|
|
101
|
+
|
|
74
102
|
function setSubscript(string, index) {
|
|
75
103
|
subscripts.set(string, index + "");
|
|
76
104
|
}
|
|
@@ -87,15 +115,16 @@ export default class Stack extends Transform {
|
|
|
87
115
|
walk(object.body, [object, ...parents], (o, p) => {
|
|
88
116
|
if (o.type == "Identifier") {
|
|
89
117
|
var info = getIdentifierInfo(o, p);
|
|
90
|
-
if (!info.spec.isReferenced) {
|
|
118
|
+
if (!info.spec.isReferenced || info.spec.isExported) {
|
|
91
119
|
return;
|
|
92
120
|
}
|
|
121
|
+
|
|
93
122
|
var c = info.spec.isDefined
|
|
94
123
|
? getDefiningContext(o, p)
|
|
95
124
|
: getReferencingContexts(o, p).find((x) => isVarContext(x));
|
|
96
125
|
|
|
97
126
|
if (c !== object) {
|
|
98
|
-
this.log(o.name + " is illegal due to different context");
|
|
127
|
+
// this.log(o.name + " is illegal due to different context");
|
|
99
128
|
illegal.add(o.name);
|
|
100
129
|
}
|
|
101
130
|
|
|
@@ -104,9 +133,9 @@ export default class Stack extends Transform {
|
|
|
104
133
|
info.isFunctionParameter ||
|
|
105
134
|
isForInitialize(o, p)
|
|
106
135
|
) {
|
|
107
|
-
this.log(
|
|
108
|
-
|
|
109
|
-
);
|
|
136
|
+
// this.log(
|
|
137
|
+
// o.name + " is illegal due to clause parameter/function parameter"
|
|
138
|
+
// );
|
|
110
139
|
illegal.add(o.name);
|
|
111
140
|
}
|
|
112
141
|
if (o.hidden) {
|
|
@@ -119,22 +148,53 @@ export default class Stack extends Transform {
|
|
|
119
148
|
}
|
|
120
149
|
|
|
121
150
|
if (info.isFunctionDeclaration) {
|
|
122
|
-
|
|
151
|
+
ok(p[0].type === "FunctionDeclaration");
|
|
152
|
+
if (
|
|
153
|
+
p[0] !== object.body.body[0] ||
|
|
154
|
+
!isTransformableFunction(p[0])
|
|
155
|
+
) {
|
|
123
156
|
illegal.add(o.name);
|
|
124
157
|
}
|
|
125
158
|
}
|
|
126
159
|
|
|
127
|
-
|
|
160
|
+
// The new accessors will either be numbered: [index] or as a string .string
|
|
161
|
+
var newSubscript = choice([
|
|
162
|
+
subscripts.size,
|
|
163
|
+
propertyGen.generate(),
|
|
164
|
+
]);
|
|
165
|
+
|
|
166
|
+
setSubscript(o.name, newSubscript);
|
|
128
167
|
defined.add(o.name);
|
|
129
168
|
|
|
169
|
+
// Stack can only process single VariableDeclarations
|
|
130
170
|
var varIndex = p.findIndex((x) => x.type == "VariableDeclaration");
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
171
|
+
|
|
172
|
+
if (varIndex !== -1) {
|
|
173
|
+
// Invalid 'id' property (must be Identifier)
|
|
174
|
+
if (varIndex !== 2) {
|
|
175
|
+
illegal.add(o.name);
|
|
176
|
+
} else if (p[varIndex].declarations.length > 1) {
|
|
177
|
+
illegal.add(o.name);
|
|
178
|
+
} else {
|
|
179
|
+
var value = p[varIndex].declarations[0].init;
|
|
180
|
+
if (value && !isTransformableFunction(value)) {
|
|
181
|
+
illegal.add(o.name);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
136
184
|
}
|
|
137
185
|
} else if (info.spec.isReferenced) {
|
|
186
|
+
if (info.spec.isModified) {
|
|
187
|
+
var assignmentIndex = p.findIndex(
|
|
188
|
+
(x) => x.type === "AssignmentExpression"
|
|
189
|
+
);
|
|
190
|
+
if (assignmentIndex !== -1) {
|
|
191
|
+
var value = p[assignmentIndex].right;
|
|
192
|
+
if (value && !isTransformableFunction(value)) {
|
|
193
|
+
illegal.add(o.name);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
138
198
|
referenced.add(o.name);
|
|
139
199
|
}
|
|
140
200
|
}
|
|
@@ -160,16 +220,17 @@ export default class Stack extends Transform {
|
|
|
160
220
|
return;
|
|
161
221
|
}
|
|
162
222
|
|
|
163
|
-
|
|
223
|
+
const numberLiteral = (number: number | string, depth = 0): Node => {
|
|
164
224
|
ok(number === number);
|
|
165
225
|
if (
|
|
166
226
|
typeof number !== "number" ||
|
|
167
227
|
!Object.keys(deadValues).length ||
|
|
168
|
-
depth >
|
|
169
|
-
|
|
228
|
+
depth > 4 ||
|
|
229
|
+
chance(75 + depth * 15 + this.mangledExpressionsMade / 25)
|
|
170
230
|
) {
|
|
171
231
|
return Literal(number);
|
|
172
232
|
}
|
|
233
|
+
this.mangledExpressionsMade++;
|
|
173
234
|
|
|
174
235
|
var opposingIndex = choice(Object.keys(deadValues));
|
|
175
236
|
if (typeof opposingIndex === "undefined") {
|
|
@@ -193,7 +254,7 @@ export default class Stack extends Transform {
|
|
|
193
254
|
),
|
|
194
255
|
numberLiteral(actualValue - number, depth + 1)
|
|
195
256
|
);
|
|
196
|
-
}
|
|
257
|
+
};
|
|
197
258
|
|
|
198
259
|
function getMemberExpression(index) {
|
|
199
260
|
ok(typeof index === "string", typeof index);
|
|
@@ -204,8 +265,7 @@ export default class Stack extends Transform {
|
|
|
204
265
|
);
|
|
205
266
|
}
|
|
206
267
|
|
|
207
|
-
var stackName = this.getPlaceholder();
|
|
208
|
-
var made = 1;
|
|
268
|
+
var stackName = this.getPlaceholder() + "_stack";
|
|
209
269
|
|
|
210
270
|
const scan = (o, p) => {
|
|
211
271
|
if (o.type == "Identifier") {
|
|
@@ -287,10 +347,9 @@ export default class Stack extends Transform {
|
|
|
287
347
|
typeof o.value === "number" &&
|
|
288
348
|
Math.floor(o.value) === o.value &&
|
|
289
349
|
Math.abs(o.value) < 100_000 &&
|
|
290
|
-
|
|
291
|
-
|
|
350
|
+
p.find((x) => isFunction(x)) === object &&
|
|
351
|
+
chance(50)
|
|
292
352
|
) {
|
|
293
|
-
made++;
|
|
294
353
|
return () => {
|
|
295
354
|
this.replaceIdentifierOrLiteral(o, numberLiteral(o.value, 0), p);
|
|
296
355
|
};
|
|
@@ -302,10 +361,10 @@ export default class Stack extends Transform {
|
|
|
302
361
|
object.body.body.forEach((stmt, index) => {
|
|
303
362
|
var isFirst = index == 0;
|
|
304
363
|
|
|
305
|
-
if (isFirst ||
|
|
364
|
+
if (isFirst || chance(50 - index * 10)) {
|
|
306
365
|
var exprs = [];
|
|
307
366
|
|
|
308
|
-
var changes = getRandomInteger(
|
|
367
|
+
var changes = getRandomInteger(1, 3);
|
|
309
368
|
|
|
310
369
|
for (var i = 0; i < changes; i++) {
|
|
311
370
|
var expr;
|
|
@@ -318,8 +377,10 @@ export default class Stack extends Transform {
|
|
|
318
377
|
var newIndex;
|
|
319
378
|
var i = 0;
|
|
320
379
|
do {
|
|
321
|
-
newIndex =
|
|
322
|
-
|
|
380
|
+
newIndex = choice([
|
|
381
|
+
propertyGen.generate(),
|
|
382
|
+
getRandomInteger(0, 250 + subscripts.size + i * 1000) + "",
|
|
383
|
+
]);
|
|
323
384
|
i++;
|
|
324
385
|
} while (valueSet.has(newIndex));
|
|
325
386
|
|
|
@@ -342,10 +403,10 @@ export default class Stack extends Transform {
|
|
|
342
403
|
break;
|
|
343
404
|
|
|
344
405
|
case "deadValue":
|
|
345
|
-
var rand = getRandomInteger(-
|
|
406
|
+
var rand = getRandomInteger(-150, 150);
|
|
346
407
|
|
|
347
408
|
// modify an already existing dead value index
|
|
348
|
-
if (
|
|
409
|
+
if (chance(50)) {
|
|
349
410
|
var alreadyExisting = choice(Object.keys(deadValues));
|
|
350
411
|
|
|
351
412
|
if (typeof alreadyExisting === "string") {
|
|
@@ -359,7 +420,6 @@ export default class Stack extends Transform {
|
|
|
359
420
|
numberLiteral(rand)
|
|
360
421
|
);
|
|
361
422
|
|
|
362
|
-
ok(!subscripts.has(newIndex));
|
|
363
423
|
deadValues[newIndex] = rand;
|
|
364
424
|
break;
|
|
365
425
|
}
|
|
@@ -413,7 +473,7 @@ export default class Stack extends Transform {
|
|
|
413
473
|
// Ensure the array is correct length
|
|
414
474
|
prepend(
|
|
415
475
|
object.body,
|
|
416
|
-
Template(`${stackName}
|
|
476
|
+
Template(`${stackName}["length"] = ${startingSize}`).single()
|
|
417
477
|
);
|
|
418
478
|
};
|
|
419
479
|
}
|
|
@@ -7,7 +7,120 @@ const Encoding: {
|
|
|
7
7
|
template: ReturnType<typeof Template>;
|
|
8
8
|
};
|
|
9
9
|
} = {
|
|
10
|
-
|
|
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;
|