Created
November 30, 2020 07:08
-
-
Save yihong0618/7db0ad82d97c642eb5537d026431739e to your computer and use it in GitHub Desktop.
shanbay decode
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Func { | |
static loop(cnt, func) { | |
'v' | |
.repeat(cnt) | |
.split('') | |
.map((_, idx) => func(idx)); | |
} | |
} | |
class Num { | |
static get(num) { | |
return num >>> 0; | |
} | |
static xor(a, b) { | |
return this.get(this.get(a) ^ this.get(b)); | |
} | |
static and(a, b) { | |
return this.get(this.get(a) & this.get(b)); | |
} | |
static mul(a, b) { | |
const high16 = ((a & 0xffff0000) >>> 0) * b; | |
const low16 = (a & 0x0000ffff) * b; | |
return this.get((high16 >>> 0) + (low16 >>> 0)); | |
} | |
static or(a, b) { | |
return this.get(this.get(a) | this.get(b)); | |
} | |
static not(a) { | |
return this.get(~this.get(a)); | |
} | |
static shiftLeft(a, b) { | |
return this.get(this.get(a) << b); | |
} | |
static shiftRight(a, b) { | |
return this.get(a) >>> b; | |
} | |
static mod(a, b) { | |
return this.get(this.get(a) % b); | |
} | |
} | |
const MIN_LOOP = 8; | |
const PRE_LOOP = 8; | |
const BAY_SH0 = 1; | |
const BAY_SH1 = 10; | |
const BAY_SH8 = 8; | |
const BAY_MASK = 0x7fffffff; | |
class Random { | |
constructor() { | |
this.status = []; | |
this.mat1 = 0; | |
this.mat2 = 0; | |
this.tmat = 0; | |
} | |
seed(seeds) { | |
Func.loop(4, idx => { | |
if (seeds.length > idx) { | |
this.status[idx] = Num.get(seeds.charAt(idx).charCodeAt()); | |
} else { | |
this.status[idx] = Num.get(110); | |
} | |
}); | |
[, this.mat1, this.mat2, this.tmat] = this.status; | |
this.init(); | |
} | |
init() { | |
Func.loop(MIN_LOOP - 1, idx => { | |
this.status[(idx + 1) & 3] = Num.xor( | |
this.status[(idx + 1) & 3], | |
idx + | |
1 + | |
Num.mul( | |
1812433253, | |
Num.xor(this.status[idx & 3], Num.shiftRight(this.status[idx & 3], 30)), | |
), | |
); | |
}); | |
if ( | |
(this.status[0] & BAY_MASK) === 0 && | |
this.status[1] === 0 && | |
this.status[2] === 0 && | |
this.status[3] === 0 | |
) { | |
this.status[0] = 66; | |
this.status[1] = 65; | |
this.status[2] = 89; | |
this.status[3] = 83; | |
} | |
Func.loop(PRE_LOOP, () => this.nextState()); | |
} | |
nextState() { | |
let x; | |
let y; | |
[, , , y] = this.status; | |
x = Num.xor(Num.and(this.status[0], BAY_MASK), Num.xor(this.status[1], this.status[2])); | |
x = Num.xor(x, Num.shiftLeft(x, BAY_SH0)); | |
y = Num.xor(y, Num.xor(Num.shiftRight(y, BAY_SH0), x)); | |
[, this.status[0], this.status[1]] = this.status; | |
this.status[2] = Num.xor(x, Num.shiftLeft(y, BAY_SH1)); | |
this.status[3] = y; | |
this.status[1] = Num.xor(this.status[1], Num.and(-Num.and(y, 1), this.mat1)); | |
this.status[2] = Num.xor(this.status[2], Num.and(-Num.and(y, 1), this.mat2)); | |
} | |
generate(max) { | |
this.nextState(); | |
let t0; | |
[, , , t0] = this.status; | |
const t1 = Num.xor(this.status[0], Num.shiftRight(this.status[2], BAY_SH8)); | |
t0 = Num.xor(t0, t1); | |
t0 = Num.xor(Num.and(-Num.and(t1, 1), this.tmat), t0); | |
return t0 % max; | |
} | |
} | |
class Node { | |
constructor() { | |
this.char = '.'; | |
this.children = {}; | |
} | |
getChar() { | |
return this.char; | |
} | |
getChildren() { | |
return this.children; | |
} | |
setChar(char) { | |
this.char = char; | |
} | |
setChildren(k, v) { | |
this.children[k] = v; | |
} | |
} | |
const B32_CODE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'; | |
const B64_CODE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; | |
const CNT = [1, 2, 2, 2, 2, 2]; | |
class Tree { | |
constructor() { | |
this.random = new Random(); | |
this.sign = ''; | |
this.inter = {}; | |
this.head = new Node(); | |
} | |
init(sign) { | |
this.random.seed(sign); | |
this.sign = sign; | |
Func.loop(64, i => { | |
this.addSymbol(B64_CODE[i], CNT[parseInt((i + 1) / 11, 10)]); | |
}); | |
this.inter['='] = '='; | |
} | |
addSymbol(char, len) { | |
let ptr = this.head; | |
let symbol = ''; | |
Func.loop(len, () => { | |
let innerChar = B32_CODE[this.random.generate(32)]; | |
while ( | |
innerChar in ptr.getChildren() && | |
ptr.getChildren()[innerChar].getChar() !== '.' | |
) { | |
innerChar = B32_CODE[this.random.generate(32)]; | |
} | |
symbol += innerChar; | |
if (!(innerChar in ptr.getChildren())) { | |
ptr.setChildren(innerChar, new Node()); | |
} | |
ptr = ptr.getChildren()[innerChar]; | |
}); | |
ptr.setChar(char); | |
this.inter[char] = symbol; | |
return symbol; | |
} | |
decode(enc) { | |
let dec = ''; | |
for (let i = 4; i < enc.length;) { | |
if (enc[i] === '=') { | |
dec += '='; | |
i++; | |
continue; // eslint-disable-line | |
} | |
let ptr = this.head; | |
while (enc[i] in ptr.getChildren()) { | |
ptr = ptr.getChildren()[enc[i]]; | |
i++; | |
} | |
dec += ptr.getChar(); | |
} | |
return dec; | |
} | |
/* client maybe never use it. | |
encode(ori) { | |
let enc = this.sign; | |
for (let i = 0; i < ori.length; ++i) { | |
enc += this.inter[ori[i]]; | |
} | |
return enc; | |
} | |
*/ | |
} | |
const getIdx = c => { | |
const x = c.charCodeAt(); | |
if (x >= 65) { | |
return x - 65; | |
} | |
return x - 65 + 41; | |
}; | |
const VERSION = 1; | |
const checkVersion = s => { | |
const wi = getIdx(s[0]) * 32 + getIdx(s[1]); | |
const x = getIdx(s[2]); | |
const check = getIdx(s[3]); | |
return VERSION >= (wi * x + check) % 32; | |
}; | |
const decode = enc => { | |
if (!checkVersion(enc)) { | |
return ''; | |
} | |
const tree = new Tree(); | |
tree.init(enc.substr(0, 4)); | |
const rawEncode = tree.decode(enc); | |
let buff = new Buffer(rawEncode, 'base64'); | |
return buff.toString('utf8'); | |
}; | |
console.log(decode("UYLZ3N32CDTNRQS6XNKGLL6NN7DABMDTN7G66NKDTHIWGVDGJ4DTLPW7VP6XAQONTNRQSDTVPNCVP7DTLPW7VPMNL5CQYHCQSQKNTHI32GVDGZM76X2S5W==")) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
just make shanbay_remember work again.
FYI:
cookie only live three days. And I will not add login things because
you know
reason.if you want all things automatically you need DIY it.