Tôi đã viết một số mã JS bằng một số ý tưởng trong chuỗi này:
const BITS = 32n;
const MAX = 4294967295n;
const COPRIME = 65521n;
const INVERSE = 2166657316n;
const ROT = 6n;
const XOR1 = 10296065n;
const XOR2 = 2426476569n;
function rotRight(n, bits, size) {
const mask = (1n << bits) - 1n;
// console.log('mask',mask.toString(2).padStart(Number(size),'0'));
const left = n & mask;
const right = n >> bits;
return (left << (size - bits)) | right;
}
const pipe = fns => fns.reduce((f, g) => (...args) => g(f(...args)));
function build(...fns) {
const enc = fns.map(f => Array.isArray(f) ? f[0] : f);
const dec = fns.map(f => Array.isArray(f) ? f[1] : f).reverse();
return [
pipe(enc),
pipe(dec),
]
}
[exports.encode, exports.decode] = build(
[BigInt, Number],
[i => (i * COPRIME) % MAX, i => (i * INVERSE) % MAX],
x => x ^ XOR1,
[x => rotRight(x, ROT, BITS), x => rotRight(x, BITS-ROT, BITS)],
x => x ^ XOR2,
);
Nó tạo ra một số kết quả tốt đẹp như:
1 1352888202n 1 'mdh37u'
2 480471946n 2 '7y26iy'
3 3634587530n 3 '1o3xtoq'
4 2225300362n 4 '10svwqy'
5 1084456843n 5 'hxno97'
6 212040587n 6 '3i8rkb'
7 3366156171n 7 '1jo4eq3'
8 3030610827n 8 '1e4cia3'
9 1889750920n 9 'v93x54'
10 1017334664n 10 'gtp0g8'
11 4171450248n 11 '1wzknm0'
12 2762163080n 12 '19oiqo8'
13 1621319561n 13 'qtai6h'
14 748903305n 14 'cdvlhl'
15 3903018889n 15 '1sjr8nd'
16 3567473545n 16 '1mzzc7d'
17 2426613641n 17 '144qr2h'
18 1554197390n 18 'ppbudq'
19 413345678n 19 '6u3fke'
20 3299025806n 20 '1ik5klq'
21 2158182286n 21 'zoxc3y'
22 1285766031n 22 'l9iff3'
23 144914319n 23 '2ea0lr'
24 4104336271n 24 '1vvm64v'
25 2963476367n 25 '1d0dkzz'
26 2091060108n 26 'ykyob0'
27 950208396n 27 'fpq9ho'
28 3835888524n 28 '1rfsej0'
29 2695045004n 29 '18kk618'
30 1822628749n 30 'u559cd'
31 681777037n 31 'b9wuj1'
32 346231693n 32 '5q4y31'
Thử nghiệm với:
const {encode,decode} = require('./obfuscate')
for(let i = 1; i <= 1000; ++i) {
const j = encode(i);
const k = decode(j);
console.log(i, j, k, j.toString(36));
}
XOR1
và XOR2
chỉ là các số ngẫu nhiên từ 0 đến MAX
. MAX
là 2**32-1
; bạn nên đặt giá trị này thành bất kỳ giá trị nào bạn cho rằng ID cao nhất của mình sẽ là.
COPRIME
là một số có cùng chuẩn với w / MAX
. Tôi nghĩ rằng bản thân các số nguyên tố là nguyên tố với mọi số khác (ngoại trừ bội số của chúng).
INVERSE
là một trong những khó khăn để tìm ra. Những bài đăng trên blog này không đưa ra câu trả lời thẳng thắn, nhưng WolframAlpha có thể tìm ra câu trả lời cho bạn . Về cơ bản, chỉ cần giải phương trình (COPRIME * x) % MAX = 1
cho x
.
Các build
chức năng là điều mà tôi tạo ra để làm cho nó dễ dàng hơn để tạo ra những đường ống dẫn mã hóa / giải mã. Bạn có thể cung cấp cho nó bao nhiêu thao tác tùy thích theo [encode, decode]
từng cặp. Các chức năng này phải bằng nhau và trái dấu. Các XOR
chức năng là những lời khen ngợi riêng của họ, vì vậy bạn không cần một cặp ở đó.
Đây là một niềm vui sự co hồi :
function mixHalves(n) {
const mask = 2n**12n-1n;
const right = n & mask;
const left = n >> 12n;
const mix = left ^ right;
return (mix << 12n) | right;
}
(giả sử số nguyên 24 bit - chỉ cần thay đổi các số cho bất kỳ kích thước nào khác)