ฉันเขียนโค้ด JS โดยใช้แนวคิดบางอย่างในเธรดนี้:
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,
);
มันให้ผลลัพธ์ที่ดีเช่น:
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'
ทดสอบกับ:
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
และXOR2
เป็นเพียงตัวเลขสุ่มระหว่าง 0 MAX
และ MAX
คือ2**32-1
; คุณควรตั้งค่านี้เป็นสิ่งที่คุณคิดว่า ID สูงสุดของคุณจะเป็น
COPRIME
เป็นตัวเลขที่มีMAX
ปัญหาร่วมกัน ฉันคิดว่าจำนวนเฉพาะนั้นมีความสัมพันธ์กันกับจำนวนอื่น ๆ (ยกเว้นตัวคูณของตัวมันเอง)
INVERSE
เป็นเรื่องยุ่งยากที่จะคิดออก บล็อกโพสต์เหล่านี้ไม่ได้ให้คำตอบที่ตรง แต่WolframAlpha สามารถหาคำตอบให้คุณได้ โดยทั่วไปเพียงแค่การแก้สมการสำหรับ(COPRIME * x) % MAX = 1
x
build
ฟังก์ชั่นเป็นสิ่งที่ผมสร้างขึ้นเพื่อให้ง่ายต่อการสร้างการเข้ารหัส / ถอดรหัสท่อเหล่านี้ คุณสามารถป้อนการดำเนินการได้มากเท่าที่คุณต้องการเป็น[encode, decode]
คู่ ฟังก์ชันเหล่านี้จะต้องเท่ากันและตรงกันข้าม XOR
ฟังก์ชั่นการชมเชยของตัวเองเพื่อให้คุณไม่จำเป็นต้องมีคู่
นี่เป็นอีกหนึ่งการคิดค้นที่สนุก:
function mixHalves(n) {
const mask = 2n**12n-1n;
const right = n & mask;
const left = n >> 12n;
const mix = left ^ right;
return (mix << 12n) | right;
}
(สมมติว่าเป็นจำนวนเต็ม 24 บิต - เพียงแค่เปลี่ยนตัวเลขสำหรับขนาดอื่น ๆ )