Skip to content

Commit 0a88c1d

Browse files
committed
Initial commit
0 parents  commit 0a88c1d

14 files changed

+459
-0
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
decrypt

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2018 Ganlv
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.

README.md

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Lua 简单异或加密
2+
3+
## LICENSE
4+
5+
The MIT License (MIT)
6+
7+
Copyright (c) 2018 Ganlv
8+
9+
Permission is hereby granted, free of charge, to any person obtaining a copy
10+
of this software and associated documentation files (the "Software"), to deal
11+
in the Software without restriction, including without limitation the rights
12+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
copies of the Software, and to permit persons to whom the Software is
14+
furnished to do so, subject to the following conditions:
15+
16+
The above copyright notice and this permission notice shall be included in
17+
all copies or substantial portions of the Software.

data/templates.lua

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
-- Lua simple XOR encrypt by Ganlv
2+
-- key = gg.prompt({"请输入密码:"}, {""}, {"text"})
3+
key = "把这里替换成密码"
4+
-- load
5+
local main = loadstring((function (bytes, key)
6+
-- http://lua-users.org/wiki/BitUtils
7+
function bxor(a, b)
8+
local r = 0
9+
for i = 0, 31 do
10+
local x = a / 2 + b / 2
11+
if x ~= math.floor(x) then
12+
r = r + 2 ^ i
13+
end
14+
a = math.floor(a / 2)
15+
b = math.floor(b / 2)
16+
end
17+
return r
18+
end
19+
20+
local getDataBytes = function (bytes)
21+
local result = {}
22+
local i = 1
23+
local index = bytes[i]
24+
while (index >= 0) do
25+
result[i] = bytes[index + 1]
26+
i = i + 1
27+
index = bytes[i]
28+
end
29+
return result
30+
end
31+
32+
local decode = function (bytes, key)
33+
if #key <= 0 then
34+
return {}
35+
end
36+
local i = 1
37+
local j = 1
38+
for i = 1, #bytes do
39+
bytes[i] = bxor(bytes[i], string.byte(key, j))
40+
j = j + 1
41+
if j > #key then
42+
j = 1
43+
end
44+
end
45+
return bytes
46+
end
47+
48+
local bytesToString = function (bytes)
49+
local result = ""
50+
for i = 1, #bytes do
51+
result = result .. string.char(bytes[i])
52+
end
53+
return result
54+
end
55+
56+
return bytesToString(decode(getDataBytes(bytes), key))
57+
end)({
58+
-- data
59+
}, key))
60+
if main then
61+
main()
62+
else
63+
print("密码错误")
64+
end

dist/bundle.js

+40
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/index.html

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<meta charset="UTF-8">
2+
<script src="bundle.js"></script>
3+
<p><label for="files">选择Lua文件:</label><input type="file" id="files"></p>
4+
<p><label for="key">密码:</label><input type="text" id="key"></p>
5+
<p><label for="is-gg">是否是GG修改器:</label><input type="checkbox" id="is-gg">(是GG修改器则勾选,会以弹窗形式要求输入密码。不勾选则需要用户手动修改文件填写密码)</p>
6+
<p><label for="lua-version">Lua版本:</label><input type="text" id="lua-version" value="5.2">(通常情况下:GG修改器填5.2,鼠标宏填5.1)</p>
7+
<p><button id="encrypt">输出加密文件</button></p>

package-lock.json

+46
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "lua-simple-encrypt",
3+
"version": "1.0.0",
4+
"description": "Lua simple XOR encrypt.",
5+
"main": "index.js",
6+
"scripts": {
7+
"test": "echo \"Error: no test specified\" && exit 1"
8+
},
9+
"keywords": [
10+
"lua",
11+
"encrypt"
12+
],
13+
"author": "Ganlv",
14+
"license": "MIT",
15+
"dependencies": {
16+
"compare-version": "^0.1.2",
17+
"file-saver": "^1.3.8",
18+
"jsencrypt": "^3.0.0-beta.1",
19+
"lodash": "^4.17.10",
20+
"luamin": "^1.0.4",
21+
"utf8": "^3.0.0"
22+
}
23+
}

src/LocalFileLoader.js

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/** @link https://stackoverflow.com/questions/3582671/how-to-open-a-local-disk-file-with-javascript/26298948#26298948 */
2+
function readAsByteArray(file, callback) {
3+
let reader = new FileReader();
4+
reader.onload = function (e) {
5+
let arrayBuffer = e.target.result;
6+
let uint8Array = new Uint8Array(arrayBuffer);
7+
let array = [].slice.call(uint8Array);
8+
callback(array, file);
9+
};
10+
reader.readAsArrayBuffer(file);
11+
}
12+
13+
exports.readAsByteArray = readAsByteArray;

src/LuaSimpleXorEncrypt.js

+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
const SimpleXorEncrypt = require('./SimpleXorEncrypt');
2+
const ShuffleWithKey = require('./ShuffleWithKey');
3+
const compareVersion = require('compare-version');
4+
const luamin = require('luamin');
5+
6+
const templates = {
7+
credit: '-- Lua simple XOR encrypt by Ganlv\n',
8+
main: 'local main = ',
9+
decoder: '((function (bytes, key)\n' +
10+
' -- http://lua-users.org/wiki/BitUtils\n' +
11+
' function bxor(a, b)\n' +
12+
' local r = 0\n' +
13+
' for i = 0, 31 do\n' +
14+
' local x = a / 2 + b / 2\n' +
15+
' if x ~= math.floor(x) then\n' +
16+
' r = r + 2 ^ i\n' +
17+
' end\n' +
18+
' a = math.floor(a / 2)\n' +
19+
' b = math.floor(b / 2)\n' +
20+
' end\n' +
21+
' return r\n' +
22+
' end\n' +
23+
'\n' +
24+
' local getDataBytes = function (bytes)\n' +
25+
' local result = {}\n' +
26+
' local i = 1\n' +
27+
' local index = bytes[i]\n' +
28+
' while (index >= 0) do\n' +
29+
' result[i] = bytes[index + 1]\n' +
30+
' i = i + 1\n' +
31+
' index = bytes[i]\n' +
32+
' end\n' +
33+
' return result\n' +
34+
' end\n' +
35+
'\n' +
36+
' local decode = function (bytes, key)\n' +
37+
' if #key <= 0 then\n' +
38+
' return {}\n' +
39+
' end\n' +
40+
' local i = 1\n' +
41+
' local j = 1\n' +
42+
' for i = 1, #bytes do\n' +
43+
' bytes[i] = bxor(bytes[i], string.byte(key, j))\n' +
44+
' j = j + 1\n' +
45+
' if j > #key then\n' +
46+
' j = 1\n' +
47+
' end\n' +
48+
' end\n' +
49+
' return bytes\n' +
50+
' end\n' +
51+
'\n' +
52+
' local bytesToString = function (bytes)\n' +
53+
' local result = ""\n' +
54+
' for i = 1, #bytes do\n' +
55+
' result = result .. string.char(bytes[i])\n' +
56+
' end\n' +
57+
' return result\n' +
58+
' end\n' +
59+
'\n' +
60+
' return bytesToString(decode(getDataBytes(bytes), key))\n' +
61+
'end)({',
62+
decoderEnd: '}, key))\n' +
63+
'if main then\n' +
64+
' main()\n' +
65+
'else\n' +
66+
' ',
67+
keyWrongAlertEnd: '\n' +
68+
'end'
69+
};
70+
71+
function parseOptions(options) {
72+
if (options.isGG) {
73+
if (!options.luaVersion) {
74+
options.luaVersion = '5.2';
75+
}
76+
if (!options.keyInputCode) {
77+
options.keyInputCode = 'key = gg.prompt({"请输入密码:"}, {""}, {"text"})[0]\n';
78+
}
79+
if (!options.keyWrongAlertCode) {
80+
options.keyWrongAlertCode = 'gg.alert("密码错误")';
81+
}
82+
}
83+
if (!options.luaVersion) {
84+
options.luaVersion = '5.1';
85+
}
86+
if (!options.keyInputCode) {
87+
options.keyInputCode = 'key = "把这里替换成密码"\n';
88+
}
89+
if (compareVersion(options.luaVersion, '5.2') < 0) {
90+
options.loadFunction = 'loadstring';
91+
} else {
92+
options.loadFunction = 'load';
93+
}
94+
if (!options.keyWrongAlertCode) {
95+
options.keyWrongAlertCode = 'print("密码错误")';
96+
}
97+
return options;
98+
}
99+
100+
function encrypt(bytes, key, options = {}) {
101+
options = parseOptions(options);
102+
let encryptedBytes = ShuffleWithKey.shuffle(SimpleXorEncrypt.encrypt(bytes, key), key);
103+
let code = options.keyInputCode
104+
+ templates.main
105+
+ options.loadFunction
106+
+ templates.decoder
107+
+ encryptedBytes.join(',')
108+
+ templates.decoderEnd
109+
+ options.keyWrongAlertCode
110+
+ templates.keyWrongAlertEnd;
111+
return templates.credit
112+
+ luamin.minify(code);
113+
}
114+
115+
exports.encrypt = encrypt;

src/ShuffleWithKey.js

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
const _ = require('lodash');
2+
const jsencrypt = require('jsencrypt');
3+
const JSEncrypt = jsencrypt.JSEncrypt;
4+
5+
function keyEncrypt(key) {
6+
let encrypt = new JSEncrypt();
7+
encrypt.setPublicKey(
8+
'-----BEGIN PUBLIC KEY-----\n' +
9+
'MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgH5QQw7WPEowArtgXJ44cVLSqeMH\n' +
10+
'o3js/MNm4u4gFJXB3lrbAhtU3QPj39kEkNSp7ji5E7jvEiz4HmKryTIaONwKBXpU\n' +
11+
'1OBboGYsXpdio78AAVHRAXEpNPphVN7GQE05UqVRzlZLjBfgv42sAUB5+iCF0T1R\n' +
12+
'g/uimzFodQYPLdutAgMBAAE=\n' +
13+
'-----END PUBLIC KEY-----'
14+
);
15+
let h = encrypt.getKey().encrypt(key);
16+
let result = [];
17+
for (let i = 0; i < h.length; i += 2) {
18+
result.push(parseInt(h.substr(i, 2), 16));
19+
}
20+
return result;
21+
}
22+
23+
function shuffleWithKey(bytes, key) {
24+
let result = [];
25+
let keyBytes = keyEncrypt(key);
26+
let resultLen = bytes.length + keyBytes.length;
27+
let shuffleIndices = _.shuffle(_.range(resultLen));
28+
let byteIndices = [];
29+
let keyByteIndices = _.sortBy(_.sampleSize(_.range(resultLen), keyBytes.length));
30+
let j = 0;
31+
for (let i = 0; i < resultLen; ++i) {
32+
let resultIndex = shuffleIndices[i];
33+
let keyByteIndex = _.indexOf(keyByteIndices, resultIndex);
34+
if (keyByteIndex >= 0) {
35+
result[resultIndex] = keyBytes[keyByteIndex];
36+
} else {
37+
result[resultIndex] = bytes[j++];
38+
byteIndices.push(resultIndex);
39+
}
40+
}
41+
return [result, byteIndices];
42+
}
43+
44+
function joinShuffleResult(shuffleResult) {
45+
let bytes = shuffleResult[0], byteIndices = shuffleResult[1];
46+
let byteIndicesLen = byteIndices.length;
47+
byteIndices = _.map(byteIndices, function (index) {
48+
return index + byteIndicesLen + 1;
49+
});
50+
byteIndices.push(-1);
51+
return _.concat(byteIndices, bytes);
52+
}
53+
54+
function shuffle(bytes, key) {
55+
return joinShuffleResult(shuffleWithKey(bytes, key));
56+
}
57+
58+
exports.shuffle = shuffle;
59+
60+
function unshuffle(shuffled) {
61+
let i = 0;
62+
let index;
63+
let bytes = [];
64+
while ((index = shuffled[i++]) >= 0) {
65+
bytes.push(shuffled[index]);
66+
}
67+
return bytes;
68+
}
69+
70+
exports.unshuffle = unshuffle;

0 commit comments

Comments
 (0)