js-confuser 2.0.0-alpha.5 → 2.0.1
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/ISSUE_TEMPLATE/bug_report.md +43 -43
- package/.github/ISSUE_TEMPLATE/feature_request.md +20 -20
- package/.github/workflows/node.js.yml +28 -28
- package/.prettierrc +4 -4
- package/CHANGELOG.md +1015 -989
- package/CODE_OF_CONDUCT.md +131 -131
- package/CONTRIBUTING.md +52 -52
- package/LICENSE +21 -21
- package/Migration.md +72 -71
- package/README.md +86 -78
- package/dist/constants.js +43 -43
- package/dist/index.js +14 -23
- package/dist/obfuscator.js +31 -25
- package/dist/order.js +4 -4
- package/dist/presets.js +31 -31
- package/dist/templates/integrityTemplate.js +4 -4
- package/dist/templates/template.js +1 -2
- package/dist/transforms/astScrambler.js +1 -2
- package/dist/transforms/calculator.js +1 -2
- package/dist/transforms/controlFlowFlattening.js +93 -63
- package/dist/transforms/deadCode.js +1 -2
- package/dist/transforms/dispatcher.js +4 -5
- package/dist/transforms/extraction/duplicateLiteralsRemoval.js +1 -2
- package/dist/transforms/extraction/objectExtraction.js +1 -2
- package/dist/transforms/finalizer.js +1 -2
- package/dist/transforms/flatten.js +1 -2
- package/dist/transforms/identifier/globalConcealing.js +15 -2
- package/dist/transforms/identifier/movedDeclarations.js +8 -7
- package/dist/transforms/identifier/renameVariables.js +7 -7
- package/dist/transforms/lock/integrity.js +11 -10
- package/dist/transforms/lock/lock.js +2 -3
- package/dist/transforms/minify.js +11 -29
- package/dist/transforms/opaquePredicates.js +1 -2
- package/dist/transforms/pack.js +5 -2
- package/dist/transforms/plugin.js +18 -19
- package/dist/transforms/preparation.js +16 -16
- package/dist/transforms/renameLabels.js +1 -2
- package/dist/transforms/rgf.js +8 -9
- package/dist/transforms/shuffle.js +1 -2
- package/dist/transforms/string/encoding.js +1 -2
- package/dist/transforms/string/stringCompression.js +3 -4
- package/dist/transforms/string/stringConcealing.js +8 -3
- package/dist/transforms/string/stringEncoding.js +1 -2
- package/dist/transforms/variableMasking.js +1 -2
- package/dist/utils/NameGen.js +2 -2
- package/dist/utils/PredicateGen.js +1 -2
- package/dist/utils/ast-utils.js +87 -88
- package/dist/utils/function-utils.js +8 -8
- package/dist/utils/node.js +5 -6
- package/dist/utils/object-utils.js +4 -4
- package/dist/utils/random-utils.js +20 -20
- package/dist/utils/static-utils.js +1 -2
- package/dist/validateOptions.js +4 -7
- package/index.d.ts +17 -17
- package/package.json +61 -59
- package/src/constants.ts +168 -168
- package/src/index.ts +118 -118
- package/src/obfuscationResult.ts +49 -49
- package/src/obfuscator.ts +501 -497
- package/src/options.ts +407 -407
- package/src/order.ts +54 -54
- package/src/presets.ts +125 -125
- package/src/templates/bufferToStringTemplate.ts +57 -57
- package/src/templates/deadCodeTemplates.ts +1185 -1185
- package/src/templates/getGlobalTemplate.ts +76 -76
- package/src/templates/integrityTemplate.ts +64 -64
- package/src/templates/setFunctionLengthTemplate.ts +11 -11
- package/src/templates/stringCompressionTemplate.ts +20 -20
- package/src/templates/tamperProtectionTemplates.ts +120 -120
- package/src/templates/template.ts +224 -224
- package/src/transforms/astScrambler.ts +99 -99
- package/src/transforms/calculator.ts +99 -99
- package/src/transforms/controlFlowFlattening.ts +1716 -1664
- package/src/transforms/deadCode.ts +82 -82
- package/src/transforms/dispatcher.ts +450 -450
- package/src/transforms/extraction/duplicateLiteralsRemoval.ts +156 -158
- package/src/transforms/extraction/objectExtraction.ts +186 -186
- package/src/transforms/finalizer.ts +74 -74
- package/src/transforms/flatten.ts +421 -420
- package/src/transforms/identifier/globalConcealing.ts +315 -295
- package/src/transforms/identifier/movedDeclarations.ts +252 -251
- package/src/transforms/identifier/renameVariables.ts +328 -321
- package/src/transforms/lock/integrity.ts +117 -114
- package/src/transforms/lock/lock.ts +418 -425
- package/src/transforms/minify.ts +615 -629
- package/src/transforms/opaquePredicates.ts +100 -100
- package/src/transforms/pack.ts +239 -231
- package/src/transforms/plugin.ts +173 -173
- package/src/transforms/preparation.ts +349 -347
- package/src/transforms/renameLabels.ts +175 -175
- package/src/transforms/rgf.ts +322 -322
- package/src/transforms/shuffle.ts +82 -82
- package/src/transforms/string/encoding.ts +144 -144
- package/src/transforms/string/stringCompression.ts +128 -128
- package/src/transforms/string/stringConcealing.ts +312 -298
- package/src/transforms/string/stringEncoding.ts +80 -80
- package/src/transforms/string/stringSplitting.ts +77 -77
- package/src/transforms/variableMasking.ts +257 -257
- package/src/utils/IntGen.ts +33 -33
- package/src/utils/NameGen.ts +116 -116
- package/src/utils/PredicateGen.ts +61 -61
- package/src/utils/ast-utils.ts +663 -663
- package/src/utils/function-utils.ts +50 -50
- package/src/utils/gen-utils.ts +48 -48
- package/src/utils/node.ts +78 -78
- package/src/utils/object-utils.ts +21 -21
- package/src/utils/random-utils.ts +93 -93
- package/src/utils/static-utils.ts +66 -66
- package/src/validateOptions.ts +256 -259
- package/tsconfig.json +13 -14
- package/dist/probability.js +0 -1
- package/dist/transforms/functionOutlining.js +0 -230
- package/dist/utils/ControlObject.js +0 -125
|
@@ -1,50 +1,50 @@
|
|
|
1
|
-
import { NodePath } from "@babel/traverse";
|
|
2
|
-
import * as t from "@babel/types";
|
|
3
|
-
import { FN_LENGTH, NodeSymbol, variableFunctionName } from "../constants";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @example __JS_CONFUSER_VAR__(identifier) // true
|
|
7
|
-
* @param path
|
|
8
|
-
* @returns
|
|
9
|
-
*/
|
|
10
|
-
export function isVariableFunctionIdentifier(path: NodePath<t.Node>) {
|
|
11
|
-
if (
|
|
12
|
-
path.isIdentifier() &&
|
|
13
|
-
path.listKey === "arguments" &&
|
|
14
|
-
path.key === 0 &&
|
|
15
|
-
path.parentPath?.isCallExpression()
|
|
16
|
-
) {
|
|
17
|
-
const callee = path.parentPath.get("callee");
|
|
18
|
-
return callee.isIdentifier({ name: variableFunctionName });
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
return false;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Computes the `function.length` property given the parameter nodes.
|
|
26
|
-
*
|
|
27
|
-
* @example function abc(a, b, c = 1, ...d) {} // abc.length = 2
|
|
28
|
-
*/
|
|
29
|
-
export function computeFunctionLength(fnPath: NodePath<t.Function>): number {
|
|
30
|
-
var savedLength = (fnPath.node as NodeSymbol)[FN_LENGTH];
|
|
31
|
-
if (typeof savedLength === "number") {
|
|
32
|
-
return savedLength;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
var count = 0;
|
|
36
|
-
|
|
37
|
-
for (var parameterNode of fnPath.node.params) {
|
|
38
|
-
if (
|
|
39
|
-
parameterNode.type === "Identifier" ||
|
|
40
|
-
parameterNode.type === "ObjectPattern" ||
|
|
41
|
-
parameterNode.type === "ArrayPattern"
|
|
42
|
-
) {
|
|
43
|
-
count++;
|
|
44
|
-
} else {
|
|
45
|
-
break;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return count;
|
|
50
|
-
}
|
|
1
|
+
import { NodePath } from "@babel/traverse";
|
|
2
|
+
import * as t from "@babel/types";
|
|
3
|
+
import { FN_LENGTH, NodeSymbol, variableFunctionName } from "../constants";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @example __JS_CONFUSER_VAR__(identifier) // true
|
|
7
|
+
* @param path
|
|
8
|
+
* @returns
|
|
9
|
+
*/
|
|
10
|
+
export function isVariableFunctionIdentifier(path: NodePath<t.Node>) {
|
|
11
|
+
if (
|
|
12
|
+
path.isIdentifier() &&
|
|
13
|
+
path.listKey === "arguments" &&
|
|
14
|
+
path.key === 0 &&
|
|
15
|
+
path.parentPath?.isCallExpression()
|
|
16
|
+
) {
|
|
17
|
+
const callee = path.parentPath.get("callee");
|
|
18
|
+
return callee.isIdentifier({ name: variableFunctionName });
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Computes the `function.length` property given the parameter nodes.
|
|
26
|
+
*
|
|
27
|
+
* @example function abc(a, b, c = 1, ...d) {} // abc.length = 2
|
|
28
|
+
*/
|
|
29
|
+
export function computeFunctionLength(fnPath: NodePath<t.Function>): number {
|
|
30
|
+
var savedLength = (fnPath.node as NodeSymbol)[FN_LENGTH];
|
|
31
|
+
if (typeof savedLength === "number") {
|
|
32
|
+
return savedLength;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
var count = 0;
|
|
36
|
+
|
|
37
|
+
for (var parameterNode of fnPath.node.params) {
|
|
38
|
+
if (
|
|
39
|
+
parameterNode.type === "Identifier" ||
|
|
40
|
+
parameterNode.type === "ObjectPattern" ||
|
|
41
|
+
parameterNode.type === "ArrayPattern"
|
|
42
|
+
) {
|
|
43
|
+
count++;
|
|
44
|
+
} else {
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return count;
|
|
50
|
+
}
|
package/src/utils/gen-utils.ts
CHANGED
|
@@ -1,48 +1,48 @@
|
|
|
1
|
-
import { reservedKeywords } from "../constants";
|
|
2
|
-
import { shuffle } from "./random-utils";
|
|
3
|
-
|
|
4
|
-
export function alphabeticalGenerator(index: number) {
|
|
5
|
-
let name = "";
|
|
6
|
-
while (index > 0) {
|
|
7
|
-
var t = (index - 1) % 52;
|
|
8
|
-
var thisChar =
|
|
9
|
-
t >= 26 ? String.fromCharCode(65 + t - 26) : String.fromCharCode(97 + t);
|
|
10
|
-
name = thisChar + name;
|
|
11
|
-
index = ((index - t) / 52) | 0;
|
|
12
|
-
}
|
|
13
|
-
if (!name) {
|
|
14
|
-
name = "_";
|
|
15
|
-
}
|
|
16
|
-
return name;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export function createZeroWidthGenerator() {
|
|
20
|
-
var maxSize = 0;
|
|
21
|
-
var currentKeyWordsArray: string[] = [];
|
|
22
|
-
|
|
23
|
-
function generateArray() {
|
|
24
|
-
var result = reservedKeywords
|
|
25
|
-
.map(
|
|
26
|
-
(keyWord) =>
|
|
27
|
-
keyWord + "\u200C".repeat(Math.max(maxSize - keyWord.length, 1))
|
|
28
|
-
)
|
|
29
|
-
.filter((craftedVariableName) => craftedVariableName.length == maxSize);
|
|
30
|
-
|
|
31
|
-
if (!result.length) {
|
|
32
|
-
++maxSize;
|
|
33
|
-
return generateArray();
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return shuffle(result);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function getNextVariable(): string {
|
|
40
|
-
if (!currentKeyWordsArray.length) {
|
|
41
|
-
++maxSize;
|
|
42
|
-
currentKeyWordsArray = generateArray();
|
|
43
|
-
}
|
|
44
|
-
return currentKeyWordsArray.pop();
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return { generate: getNextVariable };
|
|
48
|
-
}
|
|
1
|
+
import { reservedKeywords } from "../constants";
|
|
2
|
+
import { shuffle } from "./random-utils";
|
|
3
|
+
|
|
4
|
+
export function alphabeticalGenerator(index: number) {
|
|
5
|
+
let name = "";
|
|
6
|
+
while (index > 0) {
|
|
7
|
+
var t = (index - 1) % 52;
|
|
8
|
+
var thisChar =
|
|
9
|
+
t >= 26 ? String.fromCharCode(65 + t - 26) : String.fromCharCode(97 + t);
|
|
10
|
+
name = thisChar + name;
|
|
11
|
+
index = ((index - t) / 52) | 0;
|
|
12
|
+
}
|
|
13
|
+
if (!name) {
|
|
14
|
+
name = "_";
|
|
15
|
+
}
|
|
16
|
+
return name;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function createZeroWidthGenerator() {
|
|
20
|
+
var maxSize = 0;
|
|
21
|
+
var currentKeyWordsArray: string[] = [];
|
|
22
|
+
|
|
23
|
+
function generateArray() {
|
|
24
|
+
var result = reservedKeywords
|
|
25
|
+
.map(
|
|
26
|
+
(keyWord) =>
|
|
27
|
+
keyWord + "\u200C".repeat(Math.max(maxSize - keyWord.length, 1))
|
|
28
|
+
)
|
|
29
|
+
.filter((craftedVariableName) => craftedVariableName.length == maxSize);
|
|
30
|
+
|
|
31
|
+
if (!result.length) {
|
|
32
|
+
++maxSize;
|
|
33
|
+
return generateArray();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return shuffle(result);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function getNextVariable(): string {
|
|
40
|
+
if (!currentKeyWordsArray.length) {
|
|
41
|
+
++maxSize;
|
|
42
|
+
currentKeyWordsArray = generateArray();
|
|
43
|
+
}
|
|
44
|
+
return currentKeyWordsArray.pop();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return { generate: getNextVariable };
|
|
48
|
+
}
|
package/src/utils/node.ts
CHANGED
|
@@ -1,78 +1,78 @@
|
|
|
1
|
-
import * as t from "@babel/types";
|
|
2
|
-
import { ok } from "assert";
|
|
3
|
-
|
|
4
|
-
export type LiteralValue = string | number | boolean | undefined | null;
|
|
5
|
-
export const createLiteral = (value: LiteralValue) => {
|
|
6
|
-
if (value === null) return t.nullLiteral();
|
|
7
|
-
if (value === undefined) return t.identifier("undefined");
|
|
8
|
-
|
|
9
|
-
switch (typeof value) {
|
|
10
|
-
case "string":
|
|
11
|
-
return t.stringLiteral(value);
|
|
12
|
-
|
|
13
|
-
case "number":
|
|
14
|
-
return numericLiteral(value);
|
|
15
|
-
|
|
16
|
-
case "boolean":
|
|
17
|
-
return t.booleanLiteral(value);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
ok(false);
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Handles both positive and negative numeric literals
|
|
25
|
-
* @param value
|
|
26
|
-
* @returns
|
|
27
|
-
*/
|
|
28
|
-
export function numericLiteral(
|
|
29
|
-
value: number
|
|
30
|
-
): t.NumericLiteral | t.UnaryExpression {
|
|
31
|
-
ok(typeof value === "number");
|
|
32
|
-
|
|
33
|
-
if (value < 0) {
|
|
34
|
-
return t.unaryExpression("-", t.numericLiteral(-value));
|
|
35
|
-
}
|
|
36
|
-
return t.numericLiteral(value);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export function deepClone(node: t.Node | t.Node[]) {
|
|
40
|
-
function deepClone(obj) {
|
|
41
|
-
// Handle non-objects like null, undefined, primitive values, or functions
|
|
42
|
-
if (obj === null || typeof obj !== "object") {
|
|
43
|
-
return obj;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Handle Date
|
|
47
|
-
if (obj instanceof Date) {
|
|
48
|
-
return new Date(obj);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Handle Array
|
|
52
|
-
if (Array.isArray(obj)) {
|
|
53
|
-
return obj.map(deepClone);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Handle Objects
|
|
57
|
-
const clonedObj = {};
|
|
58
|
-
|
|
59
|
-
// Handle string and symbol property keys
|
|
60
|
-
|
|
61
|
-
Object.getOwnPropertyNames(obj).forEach((key) => {
|
|
62
|
-
const value = obj[key];
|
|
63
|
-
clonedObj[key] = deepClone(value);
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
// Copy simple symbols (Avoid objects = infinite recursion)
|
|
67
|
-
Object.getOwnPropertySymbols(obj).forEach((symbol) => {
|
|
68
|
-
const value = obj[symbol];
|
|
69
|
-
if (typeof value !== "object") {
|
|
70
|
-
clonedObj[symbol] = deepClone(value);
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
return clonedObj;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return deepClone(node);
|
|
78
|
-
}
|
|
1
|
+
import * as t from "@babel/types";
|
|
2
|
+
import { ok } from "assert";
|
|
3
|
+
|
|
4
|
+
export type LiteralValue = string | number | boolean | undefined | null;
|
|
5
|
+
export const createLiteral = (value: LiteralValue) => {
|
|
6
|
+
if (value === null) return t.nullLiteral();
|
|
7
|
+
if (value === undefined) return t.identifier("undefined");
|
|
8
|
+
|
|
9
|
+
switch (typeof value) {
|
|
10
|
+
case "string":
|
|
11
|
+
return t.stringLiteral(value);
|
|
12
|
+
|
|
13
|
+
case "number":
|
|
14
|
+
return numericLiteral(value);
|
|
15
|
+
|
|
16
|
+
case "boolean":
|
|
17
|
+
return t.booleanLiteral(value);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
ok(false);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Handles both positive and negative numeric literals
|
|
25
|
+
* @param value
|
|
26
|
+
* @returns
|
|
27
|
+
*/
|
|
28
|
+
export function numericLiteral(
|
|
29
|
+
value: number
|
|
30
|
+
): t.NumericLiteral | t.UnaryExpression {
|
|
31
|
+
ok(typeof value === "number");
|
|
32
|
+
|
|
33
|
+
if (value < 0) {
|
|
34
|
+
return t.unaryExpression("-", t.numericLiteral(-value));
|
|
35
|
+
}
|
|
36
|
+
return t.numericLiteral(value);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function deepClone(node: t.Node | t.Node[]) {
|
|
40
|
+
function deepClone(obj) {
|
|
41
|
+
// Handle non-objects like null, undefined, primitive values, or functions
|
|
42
|
+
if (obj === null || typeof obj !== "object") {
|
|
43
|
+
return obj;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Handle Date
|
|
47
|
+
if (obj instanceof Date) {
|
|
48
|
+
return new Date(obj);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Handle Array
|
|
52
|
+
if (Array.isArray(obj)) {
|
|
53
|
+
return obj.map(deepClone);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Handle Objects
|
|
57
|
+
const clonedObj = {};
|
|
58
|
+
|
|
59
|
+
// Handle string and symbol property keys
|
|
60
|
+
|
|
61
|
+
Object.getOwnPropertyNames(obj).forEach((key) => {
|
|
62
|
+
const value = obj[key];
|
|
63
|
+
clonedObj[key] = deepClone(value);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// Copy simple symbols (Avoid objects = infinite recursion)
|
|
67
|
+
Object.getOwnPropertySymbols(obj).forEach((symbol) => {
|
|
68
|
+
const value = obj[symbol];
|
|
69
|
+
if (typeof value !== "object") {
|
|
70
|
+
clonedObj[symbol] = deepClone(value);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
return clonedObj;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return deepClone(node);
|
|
78
|
+
}
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Creates an object from the given keys and values arrays.
|
|
3
|
-
* @param keys
|
|
4
|
-
* @param values
|
|
5
|
-
*/
|
|
6
|
-
export function createObject<T>(
|
|
7
|
-
keys: string[],
|
|
8
|
-
values: T[]
|
|
9
|
-
): { [key: string]: T } {
|
|
10
|
-
if (keys.length !== values.length) {
|
|
11
|
-
throw new Error("length mismatch");
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
var newObject = {};
|
|
15
|
-
|
|
16
|
-
keys.forEach((x, i) => {
|
|
17
|
-
newObject[x] = values[i];
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
return newObject;
|
|
21
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Creates an object from the given keys and values arrays.
|
|
3
|
+
* @param keys
|
|
4
|
+
* @param values
|
|
5
|
+
*/
|
|
6
|
+
export function createObject<T>(
|
|
7
|
+
keys: string[],
|
|
8
|
+
values: T[]
|
|
9
|
+
): { [key: string]: T } {
|
|
10
|
+
if (keys.length !== values.length) {
|
|
11
|
+
throw new Error("length mismatch");
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
var newObject = {};
|
|
15
|
+
|
|
16
|
+
keys.forEach((x, i) => {
|
|
17
|
+
newObject[x] = values[i];
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
return newObject;
|
|
21
|
+
}
|
|
@@ -1,93 +1,93 @@
|
|
|
1
|
-
import { ok } from "assert";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Returns a random element from the given array
|
|
5
|
-
* @param choices Array of items
|
|
6
|
-
* @returns One of the items in the array at random
|
|
7
|
-
*/
|
|
8
|
-
export function choice<T>(choices: T[]): T {
|
|
9
|
-
var index = Math.floor(Math.random() * choices.length);
|
|
10
|
-
return choices[index];
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Returns a true/false based on the percent chance (0%-100%)
|
|
15
|
-
* @param percentChance AS A PERCENTAGE 0 - 100%
|
|
16
|
-
*/
|
|
17
|
-
export function chance(percentChance: number): boolean {
|
|
18
|
-
return Math.random() < percentChance / 100;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* **Mutates the given array**
|
|
23
|
-
* @param array
|
|
24
|
-
*/
|
|
25
|
-
export function shuffle<T>(array: T[]): T[] {
|
|
26
|
-
array.sort(() => Math.random() - 0.5);
|
|
27
|
-
return array;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Returns a random hexadecimal string.
|
|
32
|
-
*
|
|
33
|
-
* @example getRandomHexString(6) => "CA96BF"
|
|
34
|
-
* @param length
|
|
35
|
-
* @returns
|
|
36
|
-
*/
|
|
37
|
-
export function getRandomHexString(length: number) {
|
|
38
|
-
return [...Array(length)]
|
|
39
|
-
.map(() => Math.floor(Math.random() * 16).toString(16))
|
|
40
|
-
.join("")
|
|
41
|
-
.toUpperCase();
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* @see https://github.com/MichaelXF/js-confuser/issues/150#issuecomment-2466159582
|
|
46
|
-
*/
|
|
47
|
-
export function getRandomChineseString(length: number) {
|
|
48
|
-
const characters: string[] = [];
|
|
49
|
-
for (let i = 0; i < length; i++)
|
|
50
|
-
characters.push(
|
|
51
|
-
String.fromCharCode(
|
|
52
|
-
Math.floor(Math.random() * (0x9fff - 0x4e00)) + 0x4e00
|
|
53
|
-
)
|
|
54
|
-
);
|
|
55
|
-
return characters.join("");
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Returns a random string.
|
|
60
|
-
*/
|
|
61
|
-
export function getRandomString(length: number) {
|
|
62
|
-
var result = "";
|
|
63
|
-
var characters =
|
|
64
|
-
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
65
|
-
var charactersLength = characters.length;
|
|
66
|
-
for (var i = 0; i < length; i++) {
|
|
67
|
-
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
|
68
|
-
}
|
|
69
|
-
return result;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export function getRandom(min: number, max: number) {
|
|
73
|
-
return Math.random() * (max - min) + min;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export function getRandomInteger(min: number, max: number) {
|
|
77
|
-
return Math.floor(getRandom(min, max));
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export function splitIntoChunks(str: string, size: number) {
|
|
81
|
-
ok(typeof str === "string", "str must be typeof string");
|
|
82
|
-
ok(typeof size === "number", "size must be typeof number");
|
|
83
|
-
ok(Math.floor(size) === size, "size must be integer");
|
|
84
|
-
|
|
85
|
-
const numChunks = Math.ceil(str.length / size);
|
|
86
|
-
const chunks: string[] = new Array(numChunks);
|
|
87
|
-
|
|
88
|
-
for (let i = 0, o = 0; i < numChunks; ++i, o += size) {
|
|
89
|
-
chunks[i] = str.substr(o, size);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
return chunks;
|
|
93
|
-
}
|
|
1
|
+
import { ok } from "assert";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Returns a random element from the given array
|
|
5
|
+
* @param choices Array of items
|
|
6
|
+
* @returns One of the items in the array at random
|
|
7
|
+
*/
|
|
8
|
+
export function choice<T>(choices: T[]): T {
|
|
9
|
+
var index = Math.floor(Math.random() * choices.length);
|
|
10
|
+
return choices[index];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Returns a true/false based on the percent chance (0%-100%)
|
|
15
|
+
* @param percentChance AS A PERCENTAGE 0 - 100%
|
|
16
|
+
*/
|
|
17
|
+
export function chance(percentChance: number): boolean {
|
|
18
|
+
return Math.random() < percentChance / 100;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* **Mutates the given array**
|
|
23
|
+
* @param array
|
|
24
|
+
*/
|
|
25
|
+
export function shuffle<T>(array: T[]): T[] {
|
|
26
|
+
array.sort(() => Math.random() - 0.5);
|
|
27
|
+
return array;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Returns a random hexadecimal string.
|
|
32
|
+
*
|
|
33
|
+
* @example getRandomHexString(6) => "CA96BF"
|
|
34
|
+
* @param length
|
|
35
|
+
* @returns
|
|
36
|
+
*/
|
|
37
|
+
export function getRandomHexString(length: number) {
|
|
38
|
+
return [...Array(length)]
|
|
39
|
+
.map(() => Math.floor(Math.random() * 16).toString(16))
|
|
40
|
+
.join("")
|
|
41
|
+
.toUpperCase();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @see https://github.com/MichaelXF/js-confuser/issues/150#issuecomment-2466159582
|
|
46
|
+
*/
|
|
47
|
+
export function getRandomChineseString(length: number) {
|
|
48
|
+
const characters: string[] = [];
|
|
49
|
+
for (let i = 0; i < length; i++)
|
|
50
|
+
characters.push(
|
|
51
|
+
String.fromCharCode(
|
|
52
|
+
Math.floor(Math.random() * (0x9fff - 0x4e00)) + 0x4e00
|
|
53
|
+
)
|
|
54
|
+
);
|
|
55
|
+
return characters.join("");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Returns a random string.
|
|
60
|
+
*/
|
|
61
|
+
export function getRandomString(length: number) {
|
|
62
|
+
var result = "";
|
|
63
|
+
var characters =
|
|
64
|
+
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
65
|
+
var charactersLength = characters.length;
|
|
66
|
+
for (var i = 0; i < length; i++) {
|
|
67
|
+
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
|
68
|
+
}
|
|
69
|
+
return result;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function getRandom(min: number, max: number) {
|
|
73
|
+
return Math.random() * (max - min) + min;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function getRandomInteger(min: number, max: number) {
|
|
77
|
+
return Math.floor(getRandom(min, max));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function splitIntoChunks(str: string, size: number) {
|
|
81
|
+
ok(typeof str === "string", "str must be typeof string");
|
|
82
|
+
ok(typeof size === "number", "size must be typeof number");
|
|
83
|
+
ok(Math.floor(size) === size, "size must be integer");
|
|
84
|
+
|
|
85
|
+
const numChunks = Math.ceil(str.length / size);
|
|
86
|
+
const chunks: string[] = new Array(numChunks);
|
|
87
|
+
|
|
88
|
+
for (let i = 0, o = 0; i < numChunks; ++i, o += size) {
|
|
89
|
+
chunks[i] = str.substr(o, size);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return chunks;
|
|
93
|
+
}
|