// ==UserScript== // @name 自用算法包 // @namespace http://tampermonkey.net/ // @version 0.1.3 // @description 个人私用算法包 // @author Tenfond // @match https://*/* // @match http://*/* // @license AGPL-3.0 // @grant none // @downloadURL none // ==/UserScript== (function () { 'use strict'; // 大数精度位运算 // const Bit = (function () { // // 反码 // function ones_complement(a) { // a = a.split(""); // for (let i = 1; i < a.length; i++) { // if (a[0] !== a[i]) { // a[i] = "1"; // } else { // a[i] = "0"; // } // } // return a.join(""); // } // // return { // // 与 // and: function (a, b) { // a = a.toString(2); // b = b.toString(2); // if (a[0] === "-") { // a = "1" + a.substring(1); // // 获取补码 // a = (parseInt(ones_complement(a), 2) + 1).toString(2); // } else a = "0" + a; // if (b[0] === "-") { // b = "1" + b.substring(1); // // 获取补码 // b = (parseInt(ones_complement(b), 2) + 1).toString(2); // } else b = "0" + b; // if (a.length > b.length) b = b[0] + b.substring(1).padStart(a.length - 1, b[0]); // else a = a[0] + a.substring(1).padStart(b.length - 1, a[0]); // a = a.split(""); // b = b.split(""); // for (let i = 0; i < a.length; i++) { // if (a[i] === "1" && b[i] === "1") { // a[i] = "1"; // } else { // a[i] = "0"; // } // } // if (a[0] === "1") { // a = ones_complement((parseInt(a.join(""), 2) - 1).toString(2)); // a = "-" + a.substring(1); // } else { // a = a.join(""); // } // return parseInt(a, 2); // }, // // 或 // or: function (a, b) { // a = a.toString(2); // b = b.toString(2); // if (a[0] === "-") { // a = "1" + a.substring(1); // // 获取补码 // a = (parseInt(ones_complement(a), 2) + 1).toString(2); // } else a = "0" + a; // if (b[0] === "-") { // b = "1" + b.substring(1); // // 获取补码 // b = (parseInt(ones_complement(b), 2) + 1).toString(2); // } else b = "0" + b; // if (a.length > b.length) b = b[0] + b.substring(1).padStart(a.length - 1, b[0]); // else a = a[0] + a.substring(1).padStart(b.length - 1, a[0]); // a = a.split(""); // b = b.split(""); // for (let i = 0; i < a.length; i++) { // if (a[i] === "1" || b[i] === "1") { // a[i] = "1"; // } else { // a[i] = "0"; // } // } // if (a[0] === "1") { // a = ones_complement((parseInt(a.join(""), 2) - 1).toString(2)); // a = "-" + a.substring(1); // } else { // a = a.join(""); // } // return parseInt(a, 2); // }, // // 异或 // xor: function (a, b) { // a = a.toString(2); // b = b.toString(2); // if (a[0] === "-") { // a = "1" + a.substring(1); // // 获取补码 // a = (parseInt(ones_complement(a), 2) + 1).toString(2); // } else a = "0" + a; // if (b[0] === "-") { // b = "1" + b.substring(1); // // 获取补码 // b = (parseInt(ones_complement(b), 2) + 1).toString(2); // } else b = "0" + b; // if (a.length > b.length) b = b[0] + b.substring(1).padStart(a.length - 1, b[0]); // else a = a[0] + a.substring(1).padStart(b.length - 1, a[0]); // a = a.split(""); // b = b.split(""); // for (let i = 0; i < a.length; i++) { // if (a[i] !== b[i]) { // a[i] = "1"; // } else { // a[i] = "0"; // } // } // if (a[0] === "1") { // a = ones_complement((parseInt(a.join(""), 2) - 1).toString(2)); // a = "-" + a.substring(1); // } else { // a = a.join(""); // } // return parseInt(a, 2); // }, // // 非 // not: function (a) { // return -a - 1 // }, // // 左移 // shift: function (a, b) { // a = a.toString(2); // a = a.padEnd(a.length + b, "0"); // return parseInt(a, 2); // }, // // 右移 // move: function (a, b) { // a = a.toString(2); // if (a[0] === "-") { // a = "1" + a.substring(1); // // 获取补码 // a = (parseInt(ones_complement(a), 2) + 1).toString(2); // } else a = "0" + a; // b = Math.min(b, a.length - 1); // a = a[0].padEnd(b + 1, a[0]) + a.substring(1, a.length - b); // if (a[0] === "1") { // // 获取原码 // a = ones_complement((parseInt(a, 2) - 1).toString(2)); // a = "-" + a.substring(1); // } // return parseInt(a, 2); // } // } // })(); /** 梅森旋转算法中用到的变量如下所示: w:长度 生成的随机数的二进制长度 n:寄存器长度 参与旋转的随机数个数(旋转的深度) m:周期参数,用作第三阶段的偏移量 旋转算法参与旋转的中间项 r:低位掩码/低位要提取的位数 内存界限值 2 的 r 次方 - 1 x⃗ (u)kx→k(u) 和 x⃗ (l)k+1x→k+1(l) 的切分位置 a:旋转矩阵的参数 旋转算法异或基数 矩阵 AA 的最后一行 f:初始化梅森旋转链所需参数 旋转链异或值膨化量 u,s,t,l: 整数参数,移位运算的移动距离 d,b,c: 比特遮罩 s,t:TGFSR的位移量 b,c:TGFSR的掩码 u,d,l:额外梅森旋转所需的掩码和位移量 MT19937-32的参数列表如下: ·(w, n, m, r) = (32, 624, 397, 31) ·a = 9908B0DF(16) ·f = 1812433253 ·(u, d) = (11, FFFFFFFF16) ·(s, b) = (7, 9D2C568016) ·(t, c) = (15, EFC6000016) ·l = 18 MT19937-64的参数列表如下: ·(w, n, m, r) = (64, 312, 156, 31) ·a = B5026F5AA96619E9(16) ·f = 6364136223846793005 ·(u, d) = (29, 555555555555555516) ·(s, b) = (17, 71D67FFFEDA6000016) ·(t, c) = (37, FFF7EEE00000000016) ·l = 43 */ window.MT = (function () { // 新方案定义私有变量。修复部分浏览器不支持 # 定义private私有变量 const $w = Symbol(), $n = Symbol(), $m = Symbol(), $r = Symbol(), $a = Symbol(), $u = Symbol(), $d = Symbol(), $s = Symbol(), $b = Symbol(), $t = Symbol(), $c = Symbol(), $l = Symbol(), $index = Symbol(), $LinkedList = Symbol(); // 旋转算法处理旋转链 function generate(MT) { for (let i = 0n; i < MT[$n]; i++) { const lower_mask = -(1n << MT[$r]); const upper_mask = ~lower_mask; const y = (MT[$LinkedList][i] & upper_mask) + (MT[$LinkedList][(i + 1n) % MT[$n]] & lower_mask); let yA = y >> 1n; if ((y % 2n) !== 0n) { yA = yA ^ MT[$a]; } MT[$LinkedList][i] = MT[$LinkedList][(i + MT[$m]) % MT[$n]] ^ yA; } } class MT { constructor(seed = Date.now(), bit = 32) { const args = { 32: { n: 624n, m: 397n, r: 31n, a: 0x9908B0DFn, f: 1812433253n, u: 11n, d: 0xFFFFFFFFn, s: 7n, b: 0x9D2C5680n, t: 15n, c: 0xEFC60000n, l: 18n }, 64: { n: 312n, m: 156n, r: 31n, a: 0xB5026F5AA96619E9n, f: 6364136223846793005n, u: 29n, d: 0x5555555555555555n, s: 17n, b: 0x71D67FFFEDA60000n, t: 37n, c: 0xFFF7EEE000000000n, l: 43n } }; if (typeof args[bit] === "undefined") throw new Error("未定义" + bit.toString() + "bit的参数"); this[$w] = BigInt(bit); this[$n] = args[bit].n; this[$m] = args[bit].m; this[$r] = args[bit].r; this[$a] = args[bit].a; this[$u] = args[bit].u; this[$d] = args[bit].d; this[$s] = args[bit].s; this[$b] = args[bit].b; this[$t] = args[bit].t; this[$c] = args[bit].c; this[$l] = args[bit].l; this[$index] = 0n; this[$LinkedList] = [BigInt(seed)]; // 对数组其他元素进行初始化 for (let i = 1n; i < this[$n]; i++) { this[$LinkedList][i] = (args[bit].f * (this[$LinkedList][i - 1n] ^ (this[$LinkedList][i - 1n] >> (this[$w] - 2n))) + i & (1n << this[$w]) - 1n); } } // 获取随机数 next() { if (this[$index] === 0n) generate(this); let y = this[$LinkedList][this[$index]]; y = (y ^ ((y >> this[$u]) & this[$d])); y = (y ^ ((y << this[$s]) & this[$b])); y = (y ^ ((y << this[$t]) & this[$c])); y = (y ^ (y >> this[$l])); this[$index] = (this[$index] + 1n) % this[$n]; if (this[$w] <= 53n) y = parseInt(y.toString()); return y; } } return MT; })(); // 未经许可禁止抄袭算法,可以私用。 window.Key = (function () { // 定义private私有变量 const $pwd = Symbol(); // 自定义加密算法,以防数据包被破解。 class Key { // _pwd; // 火狐v68版本貌似不支持这种方式声明变量。 constructor(pwd) { // num,密码偏移量 // key,排列长度偏移量 // charCode,防止内存频繁运动,定义在外部 let key = 7n; if (typeof pwd === "string") { for (let i = 0; i < pwd.length; i++) { key = key * 31n + BigInt(pwd[i].charCodeAt(0)); } pwd = key; key = key & 0xFFFFFFFFFFFFn; } else if ((typeof pwd).match(new RegExp("(number|'bigint')"))) { // 如果密码是数值型就使用此方法作为 密码偏移量 和 排列长度偏移量 pwd = BigInt(Math.round(pwd)); key = (key * 31n + pwd) & 0xFFFFFFFFFFFFn; } else { // 如果类型不匹配就直接提出错误 console.error("Unsupported type '" + (typeof pwd) + "'. It only supports 'string' 'number' 'bigint'."); } // 让排列长度偏移量取第一个数字。加上密码转换成字符字符串的方式 this[$pwd] = (pwd >= 0n ? pwd % 8n + 2n : -(pwd % 8n) + 2n).toString() + key.toString(36); } encrypt(string, ...strings) { function resolve(string) { if (typeof string === "string" && string.length > 0) { // subStart 排列长度的起始位置。subLength 排列长度。 let subStart = string.length, subLength = parseInt(this[$pwd][0]), // encryptPool 加密池,即去除的排列长度存放在这里。result 加密后的结果。 encryptPool = [], result = ""; // stringKey 加密种子。 const MTSeed = new MT(subStart + parseInt(this[$pwd].substring(1), 36)); // 获取加密池。 while (subStart > subLength) { subStart -= subLength; encryptPool.push(string.substring(subStart, subStart + subLength)); } encryptPool.push(string.substring(0, subStart)); // 对加密池进行加密,并将加密的字符的结果放入 result 中。 for (let i = 0, j; i < subLength; i++) { for (j = 0; j < encryptPool.length; j++) { const char = encryptPool[j][i]; if (char) { let key = (char.charCodeAt(0) + MTSeed.next()) % 0x100000000; key = [Math.floor(key / 0x10000), key % 0x10000]; result += i * j % 2 === 0 ? String.fromCharCode(key[0]) + String.fromCharCode(key[1]) : String.fromCharCode(key[1]) + String.fromCharCode(key[0]); } else { break; } } } // 返回加密结果 return result; } else { // 如果加密字符串不存在就返回string return string; } } if (strings.length === 0) { return resolve(string); } else { return strings.concat(string).filter(resolve); } } /* 假设有7个字符 加密前 - 排列 ( 1 ) ( 2 3 4 ) ( 5 6 7 ) 加密中 - 排列 ︵ ︵ ︵ 5 2 1 6 3 ︶ 7 4 ︶ ︶ 加密后 - 排列 ( 5 2 1 ) ( 6 3 ) ( 7 4 ) 解密中 - 排列 ︵ ︵ ︵ 5 6 7 2 3 4 1 ︶ ︶ ︶ 解密后 - 排列 1 2 3 4 5 6 7 */ decrypt(string, ...strings) { function resolve(string) { if (typeof string === "string" && string.length > 0) { // subStart 排列长度的起始位置。desubLength 反向取加密池的长度。 let subStart = 0, desubLength = Math.ceil(string.length / 2 / parseInt(this[$pwd][0])), // decryptPool 解密池。result 解密后的结果。 decryptPool = [], result = ""; // stringKey 加密种子。 const MTSeed = new MT(string.length / 2 + parseInt(this[$pwd].substring(1), 36)); (function (MT, desubLength) { //NullCount 加密池中没有空位的池数 const NullCount = string.length / 2 % parseInt(MT[$pwd][0]); // 获取解密池 while (string.length / 2 - subStart > desubLength) { decryptPool.push(string.substring(subStart * 2, (subStart + desubLength) * 2)); subStart += desubLength; if (decryptPool.length === NullCount) desubLength--; } decryptPool.push(string.substring(subStart * 2)); })(this, desubLength); // 对解密池进行解密 并将解密结果 加入到 result(结果) 中 string = []; for (let i = 0, j; i < decryptPool.length; i++) { for (j = 0; j < desubLength; j++) { const char = i * j % 2 === 0 ? decryptPool[i][j * 2] + decryptPool[i][j * 2 + 1] : decryptPool[i][j * 2 + 1] + decryptPool[i][j * 2]; if (char) { if (typeof string[j] === "undefined") string[j] = []; string[j][i] = String.fromCharCode((char.charCodeAt(0) * 65536 + char.charCodeAt(1) + 0x100000000 - MTSeed.next()) % 65536); } } } for (let i = string.length - 1; i >= 0; i--) { result += string[i].join(""); } // 返回解密结果 return result; } else { // 如果解密字符串不存在就返回string return string; } } if (strings.length === 0) { return resolve(string); } else { return strings.concat(string).filter(resolve); } } static encrypt() { return KEY.encrypt(arguments); } static decrypt() { return KEY.decrypt(arguments); } } const KEY = new Key("Tenfond"); return Key; })(); })();