jsarmor 1.0.6 → 2.0.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/cli/index.js +194 -177
- package/core/antidebug.js +13 -15
- package/core/antivm.js +19 -0
- package/core/beautifyGuard.js +3 -7
- package/core/controlflow.js +8 -19
- package/core/deadcode.js +12 -6
- package/core/junkcode.js +11 -10
- package/core/parser.js +1 -1
- package/core/rc4.js +15 -24
- package/core/renamer.js +101 -23
- package/core/selfdefend.js +6 -9
- package/core/stringArray.js +97 -37
- package/core/stringRuntime.js +56 -0
- package/core/unicode.js +1 -5
- package/core/unicodeIdentifier.js +67 -0
- package/docs/banner.jpg +0 -0
- package/package.json +4 -3
- package/readme.md +163 -0
- package/utils/watermark.js +21 -0
- package/LICENSE +0 -76
- package/README.md +0 -217
- package/docs/shitpost +0 -1
- /package/core/{runtime.js → rumtime.js} +0 -0
package/cli/index.js
CHANGED
|
@@ -1,177 +1,194 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import fs from "fs";
|
|
4
|
-
import path from "path";
|
|
5
|
-
import chalk from "chalk";
|
|
6
|
-
import gradient from "gradient-string";
|
|
7
|
-
import cliProgress from "cli-progress";
|
|
8
|
-
import generate from "@babel/generator";
|
|
9
|
-
|
|
10
|
-
import { parseCode } from "../core/parser.js";
|
|
11
|
-
import { renameVariables } from "../core/renamer.js";
|
|
12
|
-
import { encodeStrings } from "../core/stringArray.js";
|
|
13
|
-
import { flattenControlFlow } from "../core/controlflow.js";
|
|
14
|
-
import { unicodeEscape } from "../core/unicode.js";
|
|
15
|
-
import { generateJunk } from "../core/junkcode.js";
|
|
16
|
-
|
|
17
|
-
import { injectDeadCode, generateDeadRuntime } from "../core/deadcode.js";
|
|
18
|
-
|
|
19
|
-
import { injectAntiDebug } from "../core/antidebug.js";
|
|
20
|
-
import { antiBeautify } from "../core/beautifyGuard.js";
|
|
21
|
-
import { selfDefend } from "../core/selfdefend.js";
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
outputName =
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
bar.
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
bar.
|
|
123
|
-
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
)
|
|
170
|
-
);
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
console.log(chalk.
|
|
175
|
-
console.
|
|
176
|
-
|
|
177
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from "fs";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import chalk from "chalk";
|
|
6
|
+
import gradient from "gradient-string";
|
|
7
|
+
import cliProgress from "cli-progress";
|
|
8
|
+
import generate from "@babel/generator";
|
|
9
|
+
|
|
10
|
+
import { parseCode } from "../core/parser.js";
|
|
11
|
+
import { renameVariables } from "../core/renamer.js";
|
|
12
|
+
import { encodeStrings } from "../core/stringArray.js";
|
|
13
|
+
import { flattenControlFlow } from "../core/controlflow.js";
|
|
14
|
+
import { unicodeEscape } from "../core/unicode.js";
|
|
15
|
+
import { generateJunk } from "../core/junkcode.js";
|
|
16
|
+
|
|
17
|
+
import { injectDeadCode, generateDeadRuntime } from "../core/deadcode.js";
|
|
18
|
+
|
|
19
|
+
import { injectAntiDebug } from "../core/antidebug.js";
|
|
20
|
+
import { antiBeautify } from "../core/beautifyGuard.js";
|
|
21
|
+
import { selfDefend } from "../core/selfdefend.js";
|
|
22
|
+
import { unicodeIdentifiers } from "../core/unicodeIdentifier.js";
|
|
23
|
+
import { buildStringRuntime } from "../core/stringRuntime.js";
|
|
24
|
+
import { antiVM } from "../core/antivm.js";
|
|
25
|
+
|
|
26
|
+
import { watermark } from "../utils/watermark.js";
|
|
27
|
+
|
|
28
|
+
const neon = gradient(["#00ffff","#ff00ff","#00ff9f"]);
|
|
29
|
+
|
|
30
|
+
try{
|
|
31
|
+
|
|
32
|
+
const args = process.argv.slice(2);
|
|
33
|
+
|
|
34
|
+
const command = args[0];
|
|
35
|
+
const file = args[1];
|
|
36
|
+
|
|
37
|
+
let outputName = "obf.js";
|
|
38
|
+
|
|
39
|
+
const outIndex = args.indexOf("-o");
|
|
40
|
+
|
|
41
|
+
if(outIndex !== -1 && args[outIndex+1]){
|
|
42
|
+
outputName = args[outIndex+1];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
let user = "";
|
|
46
|
+
|
|
47
|
+
const userIndex = args.indexOf("--user");
|
|
48
|
+
|
|
49
|
+
if(userIndex !== -1 && args[userIndex+1]){
|
|
50
|
+
user = args[userIndex+1];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if(!command || command === "help"){
|
|
54
|
+
|
|
55
|
+
console.log(neon(`
|
|
56
|
+
JSArmor - JavaScript Obfuscator
|
|
57
|
+
|
|
58
|
+
Usage:
|
|
59
|
+
|
|
60
|
+
jsarmor gen input.js
|
|
61
|
+
jsarmor gen input.js -o output.js
|
|
62
|
+
|
|
63
|
+
`));
|
|
64
|
+
|
|
65
|
+
process.exit(0);
|
|
66
|
+
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if(command !== "gen"){
|
|
70
|
+
|
|
71
|
+
console.log(chalk.red("Unknown command"));
|
|
72
|
+
console.log("Use: jsarmor gen input.js");
|
|
73
|
+
|
|
74
|
+
process.exit(1);
|
|
75
|
+
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if(!file){
|
|
79
|
+
|
|
80
|
+
console.log(chalk.red("Please provide input file"));
|
|
81
|
+
console.log("Usage: jsarmor gen input.js");
|
|
82
|
+
|
|
83
|
+
process.exit(1);
|
|
84
|
+
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if(!fs.existsSync(file)){
|
|
88
|
+
console.log(chalk.red(`File not found: ${file}`));
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
let code = fs.readFileSync(file,"utf8");
|
|
93
|
+
|
|
94
|
+
let shebang = "";
|
|
95
|
+
|
|
96
|
+
if(code.startsWith("#!")){
|
|
97
|
+
const end = code.indexOf("\n");
|
|
98
|
+
shebang = code.slice(0,end);
|
|
99
|
+
code = code.slice(end);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
console.log(
|
|
103
|
+
neon(`┌──────────────────────────────┐
|
|
104
|
+
│ JSArmor Version1.7 │
|
|
105
|
+
└──────────────────────────────┘`)
|
|
106
|
+
);
|
|
107
|
+
const bar = new cliProgress.SingleBar({
|
|
108
|
+
format:"progress [{bar}] {percentage}% | {value}/{total}",
|
|
109
|
+
barCompleteChar:"█",
|
|
110
|
+
barIncompleteChar:"░"
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
bar.start(7,0);
|
|
114
|
+
|
|
115
|
+
const ast = parseCode(code);
|
|
116
|
+
bar.increment();
|
|
117
|
+
|
|
118
|
+
renameVariables(ast);
|
|
119
|
+
bar.increment();
|
|
120
|
+
|
|
121
|
+
unicodeIdentifiers(ast);
|
|
122
|
+
bar.increment();
|
|
123
|
+
|
|
124
|
+
const pool = encodeStrings(ast);
|
|
125
|
+
bar.increment();
|
|
126
|
+
|
|
127
|
+
/* dead code transform */
|
|
128
|
+
injectDeadCode(ast);
|
|
129
|
+
bar.increment();
|
|
130
|
+
|
|
131
|
+
flattenControlFlow(ast);
|
|
132
|
+
bar.increment();
|
|
133
|
+
|
|
134
|
+
unicodeEscape(ast);
|
|
135
|
+
bar.increment();
|
|
136
|
+
|
|
137
|
+
bar.stop();
|
|
138
|
+
|
|
139
|
+
const output = generate.default(ast,{
|
|
140
|
+
jsescOption:{
|
|
141
|
+
minimal:true
|
|
142
|
+
}
|
|
143
|
+
}).code;
|
|
144
|
+
|
|
145
|
+
const runtimeJunk = generateDeadRuntime();
|
|
146
|
+
|
|
147
|
+
const final =
|
|
148
|
+
(shebang ? shebang + "\n" : "") +
|
|
149
|
+
watermark(user) +
|
|
150
|
+
injectAntiDebug() +
|
|
151
|
+
antiBeautify() +
|
|
152
|
+
antiVM() +
|
|
153
|
+
selfDefend() +
|
|
154
|
+
buildStringRuntime(pool) +
|
|
155
|
+
runtimeJunk +
|
|
156
|
+
generateJunk() +
|
|
157
|
+
output;
|
|
158
|
+
|
|
159
|
+
const distDir = path.join(process.cwd(),"dist");
|
|
160
|
+
|
|
161
|
+
if(!fs.existsSync(distDir)){
|
|
162
|
+
fs.mkdirSync(distDir,{recursive:true});
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const outFile = path.join(distDir, outputName);
|
|
166
|
+
|
|
167
|
+
fs.writeFileSync(outFile,final);
|
|
168
|
+
|
|
169
|
+
console.log();
|
|
170
|
+
console.log(chalk.green("✔ Parsing AST"));
|
|
171
|
+
console.log(chalk.green("✔ Variables renamed"));
|
|
172
|
+
console.log(chalk.green("✔ Strings encoded"));
|
|
173
|
+
console.log(chalk.green("✔ Dead code injected"));
|
|
174
|
+
console.log(chalk.green("✔ Control flow flattened"));
|
|
175
|
+
console.log(chalk.green("✔ Unicode escape applied"));
|
|
176
|
+
console.log();
|
|
177
|
+
console.log(chalk.bold.green("✔ Obfuscation Complete"));
|
|
178
|
+
console.log(chalk.cyan(`Output: ${outFile}`));
|
|
179
|
+
|
|
180
|
+
const originalSize = code.length;
|
|
181
|
+
const newSize = final.length;
|
|
182
|
+
|
|
183
|
+
console.log(
|
|
184
|
+
chalk.yellow(
|
|
185
|
+
`Size: ${(originalSize/1024).toFixed(2)} KB → ${(newSize/1024).toFixed(2)} KB`
|
|
186
|
+
)
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
}catch(err){
|
|
190
|
+
|
|
191
|
+
console.log(chalk.red("Obfuscation failed"));
|
|
192
|
+
console.error(err);
|
|
193
|
+
|
|
194
|
+
}
|
package/core/antidebug.js
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
export function injectAntiDebug(){
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
(function(){
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
(
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
1
|
+
export function injectAntiDebug(){
|
|
2
|
+
return `
|
|
3
|
+
|
|
4
|
+
;(function(){
|
|
5
|
+
setInterval(function(){
|
|
6
|
+
try{
|
|
7
|
+
debugger;
|
|
8
|
+
}catch(e){}
|
|
9
|
+
},3000)
|
|
10
|
+
})();
|
|
11
|
+
|
|
12
|
+
`;
|
|
13
|
+
}
|
package/core/antivm.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export function antiVM(){
|
|
2
|
+
return `
|
|
3
|
+
|
|
4
|
+
;(function(){
|
|
5
|
+
|
|
6
|
+
var s=(typeof navigator!="undefined"?navigator.userAgent:"node").toLowerCase()
|
|
7
|
+
|
|
8
|
+
if(
|
|
9
|
+
s.includes("vmware")||
|
|
10
|
+
s.includes("virtualbox")||
|
|
11
|
+
s.includes("qemu")
|
|
12
|
+
){
|
|
13
|
+
console.warn("VM detected");
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
})()
|
|
17
|
+
|
|
18
|
+
`
|
|
19
|
+
}
|
package/core/beautifyGuard.js
CHANGED
|
@@ -1,21 +1,17 @@
|
|
|
1
1
|
export function antiBeautify(){
|
|
2
|
-
|
|
3
2
|
return `
|
|
4
3
|
|
|
5
|
-
(function(){
|
|
4
|
+
;(function(){
|
|
6
5
|
|
|
7
6
|
const start=Date.now()
|
|
8
|
-
|
|
9
7
|
debugger
|
|
10
|
-
|
|
11
8
|
const end=Date.now()
|
|
12
9
|
|
|
13
|
-
if(end-start>
|
|
14
|
-
|
|
10
|
+
if(end-start>1000){
|
|
11
|
+
console.warn("Debug detected")
|
|
15
12
|
}
|
|
16
13
|
|
|
17
14
|
})();
|
|
18
15
|
|
|
19
16
|
`;
|
|
20
|
-
|
|
21
17
|
}
|
package/core/controlflow.js
CHANGED
|
@@ -93,24 +93,13 @@ Function(path){
|
|
|
93
93
|
});
|
|
94
94
|
|
|
95
95
|
const whileLoop = t.whileStatement(
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
t.
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
t.ifStatement(
|
|
105
|
-
t.binaryExpression(
|
|
106
|
-
">=",
|
|
107
|
-
t.identifier("_s"),
|
|
108
|
-
t.numericLiteral(body.length)
|
|
109
|
-
),
|
|
110
|
-
t.breakStatement()
|
|
111
|
-
)
|
|
112
|
-
|
|
113
|
-
])
|
|
96
|
+
t.binaryExpression("<", t.identifier("_s"), t.numericLiteral(body.length)),
|
|
97
|
+
t.blockStatement([
|
|
98
|
+
t.switchStatement(
|
|
99
|
+
t.identifier("_s"),
|
|
100
|
+
cases
|
|
101
|
+
)
|
|
102
|
+
])
|
|
114
103
|
);
|
|
115
104
|
|
|
116
105
|
const newBody = [];
|
|
@@ -147,4 +136,4 @@ Function(path){
|
|
|
147
136
|
}
|
|
148
137
|
});
|
|
149
138
|
|
|
150
|
-
}
|
|
139
|
+
}
|
package/core/deadcode.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import traverseModule from "@babel/traverse";
|
|
2
2
|
import * as t from "@babel/types";
|
|
3
3
|
import { randomInt } from "../utils/random.js";
|
|
4
4
|
|
|
5
|
+
const traverse = traverseModule.default;
|
|
6
|
+
|
|
5
7
|
const patterns = [
|
|
6
8
|
|
|
7
9
|
"var _a=Math.random();if(_a>2){console.log(_a)}",
|
|
@@ -17,7 +19,9 @@ const patterns = [
|
|
|
17
19
|
|
|
18
20
|
];
|
|
19
21
|
|
|
20
|
-
|
|
22
|
+
/* generate nhiều pattern */
|
|
23
|
+
|
|
24
|
+
for(let i=0;i<20;i++){
|
|
21
25
|
|
|
22
26
|
patterns.push(`
|
|
23
27
|
var _junk${i}=Math.random()*${randomInt(1,999)};
|
|
@@ -34,9 +38,11 @@ return patterns[Math.floor(Math.random()*patterns.length)];
|
|
|
34
38
|
|
|
35
39
|
}
|
|
36
40
|
|
|
41
|
+
/* AST deadcode */
|
|
42
|
+
|
|
37
43
|
export function injectDeadCode(ast){
|
|
38
44
|
|
|
39
|
-
traverse
|
|
45
|
+
traverse(ast,{
|
|
40
46
|
|
|
41
47
|
BlockStatement(path){
|
|
42
48
|
|
|
@@ -76,14 +82,14 @@ path.node.body.unshift(fake);
|
|
|
76
82
|
|
|
77
83
|
}
|
|
78
84
|
|
|
85
|
+
/* runtime deadcode */
|
|
86
|
+
|
|
79
87
|
export function generateDeadRuntime(){
|
|
80
88
|
|
|
81
89
|
let out="";
|
|
82
90
|
|
|
83
|
-
for(let i=0;i<
|
|
84
|
-
|
|
91
|
+
for(let i=0;i<10;i++){
|
|
85
92
|
out+=randomPattern()+"\n";
|
|
86
|
-
|
|
87
93
|
}
|
|
88
94
|
|
|
89
95
|
return out;
|
package/core/junkcode.js
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
export function generateJunk()
|
|
1
|
+
export function generateJunk(){
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
return `
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
var _假=Math.random()
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
function _伪(){
|
|
8
|
+
try{
|
|
9
|
+
return Function("return 1+1")()
|
|
10
|
+
}catch(e){}
|
|
11
11
|
}
|
|
12
|
-
`);
|
|
13
12
|
|
|
14
|
-
|
|
13
|
+
if(_假>2){
|
|
14
|
+
console.log(_伪())
|
|
15
|
+
}
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
`
|
|
17
18
|
|
|
18
19
|
}
|
package/core/parser.js
CHANGED
package/core/rc4.js
CHANGED
|
@@ -1,42 +1,33 @@
|
|
|
1
1
|
export function rc4(key, str){
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
let j=0
|
|
5
|
-
let x
|
|
6
|
-
let res=""
|
|
3
|
+
if(!key) throw new Error("RC4 key empty")
|
|
7
4
|
|
|
8
|
-
|
|
9
|
-
s[i]=i
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
for(let i=0;i<256;i++){
|
|
13
|
-
|
|
14
|
-
j=(j+s[i]+key.charCodeAt(i%key.length))%256
|
|
5
|
+
let s=[],j=0,x,res=""
|
|
15
6
|
|
|
16
|
-
|
|
17
|
-
s[i]=s[j]
|
|
18
|
-
s[j]=x
|
|
7
|
+
for(let i=0;i<256;i++) s[i]=i
|
|
19
8
|
|
|
9
|
+
for(let i=0;i<256;i++){
|
|
10
|
+
j=(j+s[i]+key.charCodeAt(i%key.length))&255
|
|
11
|
+
x=s[i]
|
|
12
|
+
s[i]=s[j]
|
|
13
|
+
s[j]=x
|
|
20
14
|
}
|
|
21
15
|
|
|
22
16
|
let i=0
|
|
23
17
|
j=0
|
|
24
18
|
|
|
25
19
|
for(let y=0;y<str.length;y++){
|
|
20
|
+
i=(i+1)&255
|
|
21
|
+
j=(j+s[i])&255
|
|
26
22
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
x=s[i]
|
|
31
|
-
s[i]=s[j]
|
|
32
|
-
s[j]=x
|
|
23
|
+
x=s[i]
|
|
24
|
+
s[i]=s[j]
|
|
25
|
+
s[j]=x
|
|
33
26
|
|
|
34
|
-
let k=s[(s[i]+s[j])
|
|
35
|
-
|
|
36
|
-
res+=String.fromCharCode(str.charCodeAt(y)^k)
|
|
27
|
+
let k=s[(s[i]+s[j])&255]
|
|
37
28
|
|
|
29
|
+
res += String.fromCharCode(str.charCodeAt(y) ^ k)
|
|
38
30
|
}
|
|
39
31
|
|
|
40
32
|
return res
|
|
41
|
-
|
|
42
33
|
}
|