add feistel encryption
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
const SECRET = process.env.FEISTEL_SECRET || "change-me";
|
||||
const ROUNDS = 8;
|
||||
const HALF = 20;
|
||||
const MASK = (1 << HALF) - 1;
|
||||
const CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
function roundFn(right: number, round: number): number {
|
||||
const h = new Bun.CryptoHasher("sha256").update(SECRET + ":" + round + ":" + right).digest();
|
||||
return (h[0] << 12 | h[1] << 4 | h[2] >> 4) & MASK;
|
||||
}
|
||||
|
||||
function toBase62(n: number): string {
|
||||
let s = "";
|
||||
for (let i = 0; i < 7; i++) { s = CHARS[n % 62] + s; n = Math.floor(n / 62); }
|
||||
return s;
|
||||
}
|
||||
|
||||
function fromBase62(s: string): number {
|
||||
let n = 0;
|
||||
for (const c of s) n = n * 62 + CHARS.indexOf(c);
|
||||
return n;
|
||||
}
|
||||
|
||||
export function encodeId(val: number): string {
|
||||
let left = Math.floor(val / (MASK + 1)) & MASK;
|
||||
let right = val & MASK;
|
||||
for (let i = 0; i < ROUNDS; i++) {
|
||||
const tmp = (left ^ roundFn(right, i)) & MASK;
|
||||
left = right;
|
||||
right = tmp;
|
||||
}
|
||||
return toBase62(left * (MASK + 1) + right);
|
||||
}
|
||||
|
||||
export function decodeId(s: string): number {
|
||||
const val = fromBase62(s);
|
||||
let left = Math.floor(val / (MASK + 1)) & MASK;
|
||||
let right = val & MASK;
|
||||
for (let i = ROUNDS - 1; i >= 0; i--) {
|
||||
const tmp = (right ^ roundFn(left, i)) & MASK;
|
||||
right = left;
|
||||
left = tmp;
|
||||
}
|
||||
return left * (MASK + 1) + right;
|
||||
}
|
||||
Reference in New Issue
Block a user