76 lines
1.7 KiB
TypeScript
76 lines
1.7 KiB
TypeScript
import { createWriteStream } from "node:fs";
|
|
|
|
const fileName = "./passwords.json";
|
|
|
|
export async function getPasswordFor(level: number): Promise<string | null> {
|
|
try {
|
|
const file = Bun.file(fileName);
|
|
const data = await file.json();
|
|
return data[`natas${level}`];
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export async function savePassword(
|
|
level: number,
|
|
password: string
|
|
): Promise<void> {
|
|
let data = {};
|
|
|
|
try {
|
|
const file = Bun.file(fileName);
|
|
data = await file.json();
|
|
} catch (e) {}
|
|
|
|
data[`natas${level}`] = password;
|
|
createWriteStream(fileName).end();
|
|
await Bun.write(fileName, JSON.stringify(data, null, 2));
|
|
}
|
|
|
|
export function hex2bin(hex: string): number[] {
|
|
const buf = [];
|
|
for (let i = 0; i < hex.length; i += 2) {
|
|
const byte = hex.slice(i, i + 2);
|
|
buf.push(parseInt(byte, 16));
|
|
}
|
|
return buf;
|
|
}
|
|
|
|
export function bytes2str(bytes: number[]): string {
|
|
return bytes.map((c) => String.fromCharCode(c)).join("");
|
|
}
|
|
|
|
export function xor(str: string, key: string | number[]): number[] {
|
|
const result = [];
|
|
str.split("").forEach((c, idx) => {
|
|
const pIdx = idx % key.length;
|
|
let c2;
|
|
if (typeof key === "string") c2 = key.charCodeAt(pIdx);
|
|
else c2 = key[pIdx];
|
|
result.push(c.charCodeAt(0) ^ c2);
|
|
});
|
|
return result;
|
|
}
|
|
|
|
export function determinePeriod(
|
|
arr: number[],
|
|
threshold: number = 1,
|
|
limit: number = 50
|
|
): number {
|
|
let period = 1;
|
|
let lowest = null;
|
|
while (period < limit) {
|
|
let sum = 0;
|
|
for (let i = period; i < arr.length; i++) {
|
|
sum += arr[i] ^ arr[i - period];
|
|
}
|
|
console.log(period, sum);
|
|
|
|
if (sum === 0) return period;
|
|
if (lowest === null || sum < lowest[0]) lowest = [sum, period];
|
|
period += 1;
|
|
}
|
|
|
|
if (lowest <= threshold) return lowest[1];
|
|
}
|