// ==UserScript==
// @name 自用算法包
// @namespace http://tampermonkey.net/
// @version 0.1.6
// @homepage https://greasyfork.org/zh-CN/users/840688
// @description 个人私用算法包
// @author Tenfond
// @match https://*/*
// @match http://*/*
// @license AGPL-3.0
// @grant 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);
// }
// }
// })();
// // 正则表达式剔除 注释 和 行首行尾空白符
// string.replace(new RegExp("\"([^\\\\\"]*(\\\\.)?)*\"|'([^\\\\\']*(\\\\.)?)*'|`([^\\\\`]*(\\\\.)?)*`|\\/{2,}.*?[\r\n]|\\/\\*(\n|.)*?\\*\\/", "g"), function (text) {
// return new RegExp("^\\/{2,}").test(text) || new RegExp("^\\/\\*").test(text) ? "" : text;
// // 为了防止 代码行末端没有加分号压缩成一行而产生语法无效错误 的发生,这里保留换行符
// }).replace(new RegExp("\\s*\n\\s+", "g"), "\n").replace(new RegExp("^\\s+|\\s+$"), "")
// 深拷贝
Object.clone = function (o, async = false) {
// 存储已拷贝的旧对象属性的引用,和对应属性在新对象的引用
const ps = [], properties = [];
return copy(o);
// 深拷贝对象
function copy(o) {
// 如果没有继承Object就返回原值
if (!(o instanceof Object)) return o;
// 如果是Date或RegExp无属性的构造,则新构造一个。(Date.prototype).constructor === Date && (Date.prototype) === (Date.prototype).constructor.prototype,Date.prototype是不能构造的
else if ((o.constructor === Date || o.constructor === RegExp) && o !== o.constructor.prototype) return new o.constructor(o);
else {
// 如果对象是函数类型,就创建代理其内存的代理对象。如果对象继承自Array则创建[],否则就是继承自Object创建{}。
const object = Object.setPrototypeOf((typeof o === "function") ? (function () {
// @formatter:off
function Proxy() {return o.apply(this, arguments);}
// @formatter:on
delete Proxy["name"];
delete Proxy["length"];
Proxy["prototype"] = c("prototype");
return Proxy;
})() : o instanceof Array ? [] : {}, o);
const handle = function () {
clearTimeout(id);
// 函数和Array的部分属性是不可定义的,所以这里获取出来用于检测
const names = Object.getOwnPropertyNames(object);
// 遍历属性名 重新定义,如果可以定义属性就定义属性
for (const p of Object.getOwnPropertyNames(o)) if (names.indexOf(p) === -1) Object.defineProperty(object, p, (function () {
const {configurable, ...args} = Object.getOwnPropertyDescriptor(o, p);
if (args["value"] !== undefined) args["value"] = c(p);
return args;
})());
// 迭代一个对象的除Symbol以外的可枚举属性,包括继承的可枚举属性
// for (const p in o) if (ops.indexOf(p) === -1) object[p] = c(p);
// 获取对象Symbol属性 并 重新定义
for (const p of Object.getOwnPropertySymbols(o)) Object.defineProperty(object, p, (function () {
const {configurable, ...args} = Object.getOwnPropertyDescriptor(o, p);
if (args["value"] !== undefined) args["value"] = c(p);
return args;
})());
};
// 是否异步拷贝
if (async) {
var id = setTimeout(handle);
return object;
} else {
handle();
return object;
}
// 深拷贝属性
function c(p) {
// 如果 该属性值没有被定义过,就进行深拷贝并存储这个引用
// 如果引用了已拥有的属性内存地址,则让object的p属性也指向指定位置
const index = ps.indexOf(o[p]);
if (index === -1) {
if (async) {
const object = copy(o[p]);
ps.push(o[p]);
properties.push(object);
return object;
} else {
ps.push(o[p]);
const object = copy(o[p]);
properties.push(object);
return object;
}
} else return properties[index];
}
}
}
};
// 双向链表
window.LinkedList = (function () {
// 将 多个可迭代对象的对象 转换为链表的节点
function objectsToNodes(...objects) {
let next = undefined, prev = undefined, length = 0;
for (const object of objects) for (const value of object) {
const node = {value: value, next: undefined, prev: prev};
if (next !== undefined) {
prev.next = node;
prev = node;
} else next = prev = node;
length++;
}
return {next, prev, length};
}
// 创建一个在每个实例中存储私有变量的对象
const internal = Symbol("internal");
// 创建一个长度位length的双链表
function LinkedList(length = 0) {
if (this instanceof LinkedList) {
Object.defineProperty(this, internal, {
// 将多个可迭代对象转换为链表
value: {next: undefined, prev: undefined, length: 0},
writable: false,
enumerable: false
});
if (length > 0) {
this[internal].next = this[internal].prev = {value: undefined, next: undefined, prev: undefined};
this[internal].length = 1;
for (let i = 1; i < length; i++) {
this[internal].prev.next = {value: undefined, next: undefined, prev: this[internal].prev};
this[internal].prev = this[internal].prev.next;
this[internal].length++;
}
}
return this;
} else return new LinkedList(length);
}
// 将多个可迭代对象,转换为链表
LinkedList.from = function (...objects) {
const object = Object.setPrototypeOf({}, LinkedList.prototype);
Object.defineProperty(object, internal, {
// 将多个可迭代对象转换为链表
value: objectsToNodes(...objects),
writable: false,
enumerable: false
});
return object;
};
// 将多个值,合成为双链表
LinkedList.of = function (...values) {
const object = Object.setPrototypeOf({}, LinkedList.prototype);
Object.defineProperty(object, internal, {
// 将参数列表转换为链表
value: objectsToNodes(values),
writable: false,
enumerable: false
});
return object;
};
// 链表属性 和 迭代器、增删改查 方法
Object.defineProperties(LinkedList.prototype, {
length: {
enumerable: true, get: function () {
return this[internal].length;
}
}, first: {
enumerable: true, get: function () {
return this[internal].next;
}
}, last: {
get: function () {
return this[internal].prev;
}
},
// 定义迭代器,使对象可以被迭代
[Symbol.iterator]: {
value: function () {
let handle = this[internal];
return {
next: function () {
if (handle.next !== undefined) {
handle = handle.next;
return {value: handle.value, done: false};
} else return {value: undefined, done: true};
}
}
},
enumerable: false
},
// 设置类型标签
[Symbol.toStringTag]: {value: "LinkedList", writable: false, enumerable: false},
// 返回链表转换得到的数组,改变数组并不会改变链表
array: {
enumerable: false, get: function () {
let handle = this[internal].next, array = [];
while (handle !== undefined) {
if (handle.value !== undefined) array.push(handle.value);
else array.length++;
handle = handle.next;
}
return array;
}
},
// 从链表末尾添加添加一个或多个元素,并返回数组新的 length
push: {
enumerable: false, value: function (...values) {
if (values.length === 0) return this[internal].length;
const nodes = objectsToNodes(values);
if (this[internal].next !== undefined) {
this[internal].prev.next = nodes.next;
nodes.next.prev = this[internal].prev;
this[internal].prev = nodes.prev;
} else {
this[internal].next = nodes.next;
this[internal].prev = nodes.prev;
}
return this[internal].length += nodes.length;
}
},
// 从链表中移除末尾n个元素并返回移除元素的数组,如果length未定义则移除末尾1个元素并返回移除元素
pop: {
enumerable: false, value: function (length = undefined) {
if (length === undefined) {
if (this[internal].prev !== undefined) {
const handle = this[internal].prev;
this[internal].prev = handle.prev;
if (handle.prev !== undefined) handle.prev.next = undefined;
else this[internal].next = undefined;
this[internal].length--;
return handle.value;
} else return undefined;
} else {
length = Math.floor(length);
let array;
if (this[internal].prev !== undefined) {
if (length > this[internal].length) length = this[internal].length;
else if (length <= 0) return [];
array = Array(length);
let handle = this[internal].prev;
for (let i = length - 1; i >= 0; i--) {
if (handle.value !== undefined) array[i] = handle.value;
handle = handle.prev;
}
this[internal].prev = handle;
if (handle !== undefined) handle.next = undefined;
else this[internal].next = undefined;
this[internal].length -= array.length;
}
return array;
}
}
},
// 从链表前面添加添加一个或多个元素,并返回数组新的 length
unshift: {
enumerable: false, value: function (...values) {
if (values.length === 0) return this[internal].length;
const nodes = objectsToNodes(values);
if (this[internal].next !== undefined) {
this[internal].next.prev = nodes.prev;
nodes.prev.next = this[internal].next;
this[internal].next = nodes.next;
} else {
this[internal].next = nodes.next;
this[internal].prev = nodes.prev;
}
return this[internal].length += nodes.length;
}
},
// 从链表中移除前面n个元素并返回移除元素的数组,如果length未定义则移除前面1个元素并返回移除元素
shift: {
enumerable: false, value: function (length = undefined) {
if (length === undefined) {
if (this[internal].next !== undefined) {
const handle = this[internal].next;
this[internal].next = handle.next;
if (handle.next !== undefined) handle.next.prev = undefined;
else this[internal].prev = undefined;
this[internal].length--;
return handle.value;
} else return undefined;
} else {
length = Math.floor(length);
let array;
if (this[internal].next !== undefined) {
if (length > this[internal].length) length = this[internal].length;
else if (length <= 0) return [];
array = Array(length);
let handle = this[internal].next;
for (let i = 0; i < length; i++) {
if (handle.value !== undefined) array[i] = handle.value;
handle = handle.next;
}
this[internal].next = handle;
if (handle !== undefined) handle.prev = undefined;
else this[internal].prev = undefined;
this[internal].length -= array.length;
}
return array;
}
}
},
// 从链表指定位置添加一个或多个元素,并返回数组新的 length
insert: {
enumerable: false, value: function (index, ...values) {
index = Math.floor(index);
const handle = (function () {
if (isNaN(index)) return this[internal];
else if (index < 0) {
index = this[internal].length + index;
if (index < 0) return this[internal];
} else if (index > this[internal].length) return this[internal].prev;
// 就近遍历
if (index <= Math.ceil(this[internal].length / 2)) {
let handle = this[internal];
for (let i = 0; i < index; i++) handle = handle.next;
return handle;
} else {
let handle = this[internal].prev;
for (let i = this[internal].length; i > index; i--) handle = handle.prev;
return handle;
}
}).call(this);
// 添加值
if (values.length > 0) {
const nodes = objectsToNodes(values);
if (this[internal].next !== undefined) {
if (handle !== this[internal].prev) {
nodes.prev.next = handle.next;
handle.next.prev = nodes.prev;
} else this[internal].prev = nodes.prev;
handle.next = nodes.next;
if (handle !== this[internal]) nodes.next.prev = handle;
} else {
this[internal].next = nodes.next;
this[internal].prev = nodes.prev;
}
return this[internal].length += nodes.length;
}
}
},
// 从链表指定位置截取n个值并在该位置添加值,返回一个Array
splice: {
// index(可选)指定了从哪个坐标开始(包含这个坐标)移除和添加内容;如果是负值则表示从数组末位开始的第几位(从 -1 计数,这意味着 -n 是倒数第 n 个元素并且等价于 LinkedList.length-n);如果超出了数组的长度,则从数组末尾开始添加内容;如果负数的绝对值大于数组的长度 或 转换为数字为NaN,则表示开始位置为第 0 位
// length(可选)表示要移除的数组元素的个数。如果 length 大于 index 之后的元素的总数,则从 index 后面的元素都将被删除(含第 index 位)。如果 length 被省略了,或者它的值大于等于 LinkedList.length-index (也就是说,如果它大于或者等于 index 之后的所有元素的数量),那么 index 之后数组的所有元素都会被删除。如果 length 是 0 或 负数 或 转换为数字为NaN,则不移除元素。这种情况下,至少应添加一个新元素
// ...values(可选)item1, item2, ... 要添加进数组的元素,从start 位置开始。如果不指定,则 splice() 将只删除数组元素
// 返回值 由被删除的元素组成的一个数组。如果只删除了一个元素,则返回只包含一个元素的数组。如果没有删除元素,则返回空数组
enumerable: false, value: function (index = 0, length = Infinity, ...values) {
index = Math.floor(index);
length = Math.floor(length);
if (isNaN(index)) index = 0;
else if (index < 0) {
index = this[internal].length + index;
if (index < 0) index = 0;
} else if (index > this[internal].length) index = this[internal].length;
const maxDeletionLength = this[internal].length - index;
if (length > maxDeletionLength) length = maxDeletionLength;
else if (length < 0) length = 0;
const array = Array(length);
// 就近遍历
let handle, flag;
if (index <= Math.ceil(this[internal].length / 2)) {
handle = this[internal];
for (let i = 0; i < index; i++) handle = handle.next;
// 记录下标的值
flag = handle;
for (let i = 0; i < length; i++) {
handle = handle.next;
if (handle.value !== undefined) array[i] = handle.value;
}
} else {
handle = this[internal].prev;
// 在删除前,删除后 的位置
length = index + length;
for (let i = this[internal].length; i > length; i--) handle = handle.prev
// handle停留在删除后的位置,并将flag遍历到删除前的下标的值
flag = handle;
for (let i = length; i > index; i--) {
if (flag.value !== undefined) array[i - index - 1] = flag.value;
flag = flag.prev;
}
}
// 移除值
if (flag !== handle) {
flag.next = handle.next;
if (handle.next !== undefined) {
if (flag !== this[internal]) handle.next.prev = flag;
else handle.next.prev = undefined;
} else {
if (flag !== this[internal]) this[internal].prev = flag;
else this[internal].prev = undefined;
}
this[internal].length -= array.length;
}
// 添加值
if (values.length > 0) {
const nodes = objectsToNodes(values);
if (this[internal].next !== undefined) {
if (flag !== this[internal].prev) {
nodes.prev.next = flag.next;
flag.next.prev = nodes.prev;
} else this[internal].prev = nodes.prev;
flag.next = nodes.next;
if (flag !== this[internal]) nodes.next.prev = flag;
} else {
this[internal].next = nodes.next;
this[internal].prev = nodes.prev;
}
this[internal].length += nodes.length;
}
return array;
}
},
// 修改指定元素的值,返回修改前的值,若没有修改,则返回undefined;如果index={index:value,...}这样的形式,则返回对应下标修改前的map(object)对象。因为object会自动排序,所以这里不能用array
set: {
enumerable: false, value: function (index, value = undefined) {
if (value !== undefined && typeof index !== "object") {
if (isNaN(index)) return;
else if (index < 0) {
index = this[internal].length + index;
if (index < 0) return;
} else if (index > this[internal].length) return;
// 就近遍历
if (index <= Math.ceil(this[internal].length / 2)) {
let handle = this[internal].next;
for (let i = 0; i < index; i++) handle = handle.next;
const result = handle.value;
handle.value = value;
return result;
} else {
let handle = this[internal].prev;
for (let i = this[internal].length - 1; i > index; i--) handle = handle.prev;
const result = handle.value;
handle.value = value;
return result;
}
} else {
let i = 0, handle = this[internal].next, j = i, flag = handle;
const map = {};
for (let k in index) {
if (isNaN(k) || k > this[internal].length || k < 0) continue;
k = Math.floor(k);
if (Math.abs(k - i) > Math.abs(k - j)) {
i = j;
handle = flag;
}
if (Math.abs(k - i) <= k && Math.abs(k - i) <= Math.abs(k - this[internal].length)) {
if (k > i) for (; i < k; i++) handle = handle.next;
else for (; i > k; i--) handle = handle.prev;
map[k] = handle.value;
handle.value = index[k];
} else {
// 就近遍历
if (k <= Math.ceil(this[internal].length / 2)) {
flag = this[internal].next;
for (j = 0; j < k; j++) flag = flag.next
} else {
flag = this[internal].prev;
for (j = this[internal].length - 1; j > k; j--) flag = flag.prev;
}
map[k] = flag.value;
flag.value = index[k];
}
}
return map;
}
}
},
// 获取指定下标元素值,如果只输入了一个index,则返回对应index元素值;如果输入多个index,根据输入的下标按顺序返回一个数组,如果指定没找到,则以数组对应位置以空位填充;如果无参数则返回空数组
get: {
enumerable: false, value: function (...index) {
if (index.length === 1) {
index = index[0];
if (isNaN(index)) return;
else if (index < 0) {
index = this[internal].length + index;
if (index < 0) return;
} else if (index > this[internal].length) return;
// 就近遍历、
if (index <= Math.ceil(this[internal].length / 2)) {
let handle = this[internal].next;
for (let i = 0; i < index; i++) handle = handle.next
return handle.value;
} else {
let handle = this[internal].prev;
for (let i = this[internal].length - 1; i > index; i--) handle = handle.prev;
return handle.value;
}
} else {
let i = 0, handle = this[internal].next, j = i, flag = handle;
const array = [];
for (let k in index) {
if (isNaN(k) || k > this[internal].length || k < 0) {
array.length++;
continue;
}
k = Math.floor(k);
if (Math.abs(k - i) > Math.abs(k - j)) {
i = j;
handle = flag;
}
if (Math.abs(k - i) <= k && Math.abs(k - i) <= Math.abs(k - this[internal].length)) {
if (k > i) for (; i < k; i++) handle = handle.next;
else for (; i > k; i--) handle = handle.prev;
if (handle.value !== undefined) array.push(handle.value);
else array.length++;
} else {
// 就近遍历
if (k <= Math.ceil(this[internal].length / 2)) {
flag = this[internal].next;
for (j = 0; j < k; j++) flag = flag.next
} else {
flag = this[internal].prev;
for (j = this[internal].length - 1; j > k; j--) flag = flag.prev;
}
if (flag.value !== undefined) array.push(flag.value);
else array.length++;
}
}
return array;
}
}
},
// slice() 方法返回一个新的数组对象,这一对象是一个 [index,end) 范围的数组
slice: {
enumerable: false, value: function (index, end = this[internal].length) {
index = Math.floor(index);
end = Math.floor(end);
if (isNaN(index)) index = 0;
else if (index < 0) {
index = this[internal].length + index;
if (index < 0) index = 0;
} else if (index > this[internal].length) index = this[internal].length;
if (end > this[internal].length) end = this[internal].length;
else if (end < 0) end = 0;
const array = Array(end - index);
// 就近遍历
let handle;
if (index <= Math.ceil(this[internal].length / 2)) {
handle = this[internal].next;
for (let i = 0; i < index; i++) handle = handle.next;
for (let i = index; i < end; i++) {
if (handle.value !== undefined) array[i - index] = handle.value;
handle = handle.next;
}
} else {
handle = this[internal].prev;
for (let i = this[internal].length - 1; i > end; i--) handle = handle.prev;
for (let i = end - 1; i >= index; i--) {
if (handle.value !== undefined) array[i - index] = handle.value;
handle = handle.prev;
}
}
return array;
}
},
// 返回从0开始遍历,第一个指定value的下标
indexOf: {
enumerable: false, value: function (value) {
let handle = this[internal].next, index = 0;
while (handle !== undefined) {
if (handle.value === value) return index;
handle = handle.next;
index++;
}
}
},
// 返回从0开始遍历,第一个指定value的下标
lastIndexOf: {
enumerable: false, value: function (value) {
let handle = this[internal].prev, index = this[internal].length - 1;
while (handle !== undefined) {
if (handle.value === value) return index;
handle = handle.prev;
index--;
}
}
},
// 将可迭代对象,添加到链表中
concat: {
enumerable: false, value: function (...objects) {
if (objects.length === 0) return this;
const nodes = objectsToNodes(...objects);
if (this[internal].next !== undefined) {
this[internal].prev.next = nodes.next;
nodes.next.prev = this[internal].prev;
this[internal].prev = nodes.prev;
} else {
this[internal].next = nodes.next;
this[internal].prev = nodes.prev;
}
this[internal].length += nodes.length;
return this;
}
},
// 将每个元素toString并以指定分隔符连接成字符串
join: {
enumerable: false, value: function (separator = ",") {
if (this[internal].length > 0) {
let result = str(this[internal].next.value), handle = this[internal].next.next;
while (handle !== undefined) {
result += separator + str(handle.value);
handle = handle.next;
}
return result;
function str(o) {
if (o !== undefined && o !== null) return o.toString();
else return "";
}
} else return "";
}
}
});
return LinkedList;
})();
/**
* 梅森旋转算法中用到的变量如下所示:
* 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:额外梅森旋转所需的掩码和位移量
*/
window.MT = (function () {
// 新方案定义私有变量。修复部分浏览器不支持 # 定义private私有变量
const internal = Symbol("internal");
// 旋转算法处理旋转链
function generate() {
for (let i = 0n; i < this[internal].n; i++) {
const lower_mask = -(1n << this[internal].r);
const upper_mask = ~lower_mask;
const y = (this[internal].list[i] & upper_mask) + (this[internal].list[(i + 1n) % this[internal].n] & lower_mask);
let yA = y >> 1n;
if ((y % 2n) !== 0n) {
yA = yA ^ this[internal].a;
}
this[internal].list[i] = this[internal].list[(i + this[internal].m) % this[internal].n] ^ yA;
}
}
function MT(seed = Date.now(), bit = 32) {
if (this instanceof MT) {
const args = {
// MT19937-32的参数列表如下:
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
},
// MT19937-64的参数列表如下:
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的参数");
Object.defineProperty(this, internal, {
value: {
w: BigInt(bit), n: args[bit].n, m: args[bit].m, r: args[bit].r,
a: args[bit].a,
u: args[bit].u, d: args[bit].d,
s: args[bit].s, b: args[bit].b,
t: args[bit].t, c: args[bit].c,
l: args[bit].l,
index: 0n, list: [BigInt(seed)]
},
writable: false,
enumerable: false
});
// 对数组其他元素进行初始化
for (let i = 1n; i < this[internal].n; i++) {
this[internal].list[i] = (args[bit].f * (this[internal].list[i - 1n] ^ (this[internal].list[i - 1n] >> (this[internal].w - 2n))) + i & (1n << this[internal].w) - 1n);
}
return this;
} else return new MT(seed, bit);
}
Object.defineProperties(MT.prototype, {
// 获取随机数
next: {
enumerable: false, value: function () {
if (this[internal].index === 0n) generate.call(this);
let y = this[internal].list[this[internal].index];
y = (y ^ ((y >> this[internal].u) & this[internal].d));
y = (y ^ ((y << this[internal].s) & this[internal].b));
y = (y ^ ((y << this[internal].s) & this[internal].b));
y = (y ^ ((y << this[internal].t) & this[internal].c));
y = (y ^ (y >> this[internal].l));
this[internal].index = (this[internal].index + 1n) % this[internal].n;
if (this[internal].w <= 53n) y = parseInt(y.toString());
return y;
}
}
});
return MT;
})();
// 未经许可禁止抄袭算法,可以私用。
window.Key = (function () {
// 定义private私有变量
const internal = Symbol("internal");
// 自定义加密算法,以防数据包被破解。
function Key(pwd) {
if (this instanceof Key) {
// 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));
}
key = key & 0xFFFFFFFFFFFFn;
} else if ((typeof pwd).match(new RegExp("(number|'bigint')"))) {
// 如果密码是数值型就使用此方法作为 密码偏移量 和 排列长度偏移量=
key = (key * 31n + BigInt(Math.round(pwd))) & 0xFFFFFFFFFFFFn;
} else {
// 如果类型不匹配就直接提出错误
console.error("Unsupported type '" + (typeof pwd) + "'. It only supports 'string' 'number' 'bigint'.");
}
// 让排列长度偏移量取第一个数字。加上密码转换成字符字符串的方式
Object.defineProperty(this, internal, {
value: {pwd: key.toString(36)},
writable: false,
enumerable: false
});
return this;
} else return new Key(pwd);
}
Object.defineProperties(Key.prototype, {
encrypt: {
enumerable: false, value: function (string, ...strings) {
function resolve(string) {
if (typeof string === "string" && string.length > 0) {
string = string.split("");
// 加密种子。
const MTSeed = new MT(string.length + parseInt(this[internal].pwd, 36));
let result = "";
// 打乱顺序并加密
for (let i = string.length; i > 0; i--) {
const rand = MTSeed.next(); // rand[0,2^32-1]
const k = string.splice(rand % i, 1)[0].charCodeAt(0) + rand;
result += rand % 2 === 0 ?
String.fromCharCode(Math.floor(k / 0x10000)) + String.fromCharCode(Math.floor(k % 0x10000)) :
String.fromCharCode(Math.floor(k % 0x10000)) + String.fromCharCode(Math.floor(k / 0x10000));
}
// 返回加密结果
return result;
} else if (string.constructor.name === "Array") {
for (let i = 0; i < string.length; i++) {
string[i] = resolve.call(this, string[i]);
}
return string;
} else {
// 如果加密字符串不存在就返回string
return string;
}
}
if (strings.length === 0) {
return resolve.call(this, string);
} else {
return resolve.call(this, [string].concat(strings));
}
}
},
decrypt: {
enumerable: false, value: function (string, ...strings) {
function resolve(string) {
if (typeof string === "string" && string.length > 0) {
// 加密种子。
const MTSeed = new MT(string.length / 2 + parseInt(this[internal].pwd, 36));
// 解密并恢复顺序
const result = [], map = [];
for (let i = 0; i < string.length; i += 2) {
const rand = MTSeed.next(); // rand[0,2^32-1]
let k = string.substring(i, i + 2);
k = rand % 2 === 0 ?
k.charCodeAt(0) * 0x10000 + k.charCodeAt(1) :
k.charCodeAt(1) * 0x10000 + k.charCodeAt(0);
map.push([rand % ((string.length - i) / 2), String.fromCharCode(k - rand)]);
}
for (const item of map.reverse()) result.splice(item[0], 0, item[1]);
// 返回加密结果
return result.join("");
} else if (string.constructor.name === "Array") {
for (let i = 0; i < string.length; i++) {
string[i] = resolve.call(this, string[i]);
}
return string;
} else {
// 如果解密字符串不存在就返回string
return string;
}
}
if (strings.length === 0) {
return resolve.call(this, string);
} else {
return resolve.call(this, [string].concat(strings));
}
}
}
});
const KEY = new Key("Tenfond");
Object.defineProperty(Key, "encrypt", {
value: function () {
return KEY.encrypt.apply(KEY, arguments);
},
writable: false,
enumerable: false,
configurable: false
});
Object.defineProperty(Key, "decrypt", {
value: function () {
return KEY.decrypt.apply(KEY, arguments);
},
writable: false,
enumerable: false,
configurable: false
});
return Key;
})();
})();