Tslint is outdated for quite a while and has been replaced by eslint which now can work with TypeScript as well. This also updates dependencies and fixes all linting errors.
176 lines
6.0 KiB
TypeScript
176 lines
6.0 KiB
TypeScript
/* eslint-disable no-bitwise */
|
|
import { makeSolver } from "./utils";
|
|
|
|
function generateCRC16Table(): number[] {
|
|
let table: number[] = [];
|
|
for (let i = 0, crc = 0; i < 256; i++) {
|
|
crc = (i << 8);
|
|
for (let j = 0; j < 8; j++) {
|
|
crc = (crc << 1);
|
|
if (crc & 0x10000) {
|
|
crc = crc ^ 0x1021;
|
|
}
|
|
}
|
|
table.push(crc & 0xFFFF);
|
|
}
|
|
return table;
|
|
}
|
|
|
|
const crc16Table = generateCRC16Table();
|
|
|
|
/* For Fujitsu-Siemens. 8 or 5x4 hexadecimal digits. */
|
|
function fsiHexKeygen(serial: string): string {
|
|
|
|
function hashToString(hash: number) {
|
|
const zero = "0".charCodeAt(0);
|
|
return [12, 8, 4, 0].reduce((acc, num) => {
|
|
let temp = String.fromCharCode(zero + ((hash >> num) % 16) % 10);
|
|
return acc + temp;
|
|
}, "");
|
|
}
|
|
|
|
function calculateHash(word: string, table: number[]) {
|
|
let hash = 0;
|
|
for (let i = 0, d = 0; i < word.length; i++) {
|
|
d = table[(word.charCodeAt(i) ^ (hash >> 8)) % 256];
|
|
hash = ((hash << 8) ^ d) & 0xFFFF ;
|
|
}
|
|
return hash;
|
|
}
|
|
|
|
if (serial.length === 20) {
|
|
serial = serial.slice(12, 20);
|
|
}
|
|
|
|
return hashToString(calculateHash(serial.slice(0, 4), crc16Table)) +
|
|
hashToString(calculateHash(serial.slice(4, 8), crc16Table));
|
|
}
|
|
|
|
function codeToBytes(code: string): number[] {
|
|
const numbers = [
|
|
parseInt(code.slice(0, 5), 10),
|
|
parseInt(code.slice(5, 10), 10),
|
|
parseInt(code.slice(10, 15), 10),
|
|
parseInt(code.slice(15, 20), 10)
|
|
];
|
|
let acc = [];
|
|
for (let val of numbers) {
|
|
acc.push(val % 256);
|
|
acc.push(Math.floor(val / 256));
|
|
}
|
|
return acc;
|
|
}
|
|
|
|
/* For Fujitsu-Siemens. 5x4 dicimal digits */
|
|
function fsi20DecOldKeygen(serial: string): string {
|
|
|
|
// opArr - array with that operations do, ar1,ar2 - numbers */
|
|
function interleave(opArr: number[], ar1: number[], ar2: number[]) {
|
|
let arr = opArr.slice(0); // copy array
|
|
arr[ar1[0]] = ((opArr[ar2[0]] >> 4) | (opArr[ar2[3]] << 4)) & 0xFF;
|
|
arr[ar1[1]] = ((opArr[ar2[0]] & 0x0F) | (opArr[ar2[3]] & 0xF0));
|
|
arr[ar1[2]] = ((opArr[ar2[1]] >> 4) | (opArr[ar2[2]] << 4) & 0xFF);
|
|
arr[ar1[3]] = (opArr[ar2[1]] & 0x0F) | (opArr[ar2[2]] & 0xF0);
|
|
return arr;
|
|
}
|
|
|
|
function decryptCodeOld(bytes: number[]) {
|
|
const xorKey = ":3-v@e4i";
|
|
// apply XOR key
|
|
bytes.forEach((val, i, arr) => {
|
|
arr[i] = val ^ xorKey.charCodeAt(i);
|
|
});
|
|
// swap two bytes
|
|
[bytes[2], bytes[6]] = [bytes[6], bytes[2]];
|
|
[bytes[3], bytes[7]] = [bytes[7], bytes[3]];
|
|
bytes = interleave(bytes, [0, 1, 2, 3], [0, 1, 2, 3]);
|
|
bytes = interleave(bytes, [4, 5, 6, 7], [6, 7, 4, 5]);
|
|
// final rotations
|
|
bytes[0] = ((bytes[0] << 3) & 0xFF) | (bytes[0] >> 5);
|
|
bytes[1] = ((bytes[1] << 5) & 0xFF) | (bytes[1] >> 3);
|
|
bytes[2] = ((bytes[2] << 7) & 0xFF) | (bytes[2] >> 1);
|
|
bytes[3] = ((bytes[3] << 4) & 0xFF) | (bytes[3] >> 4);
|
|
bytes[5] = ((bytes[5] << 6) & 0xFF) | (bytes[5] >> 2);
|
|
bytes[6] = ((bytes[6] << 1) & 0xFF) | (bytes[6] >> 7);
|
|
bytes[7] = ((bytes[7] << 2) & 0xFF) | (bytes[7] >> 6);
|
|
return bytes.map((b) => (b % 36).toString(36)).join("");
|
|
}
|
|
|
|
return decryptCodeOld(codeToBytes(serial));
|
|
}
|
|
|
|
/* For Fujitsu-Simens. 6x4 decimal digits */
|
|
function fsi24DecKeygen(serial: string): string {
|
|
const xorKey = "<7#&9?>s";
|
|
const tmp = codeToBytes(serial.slice(4));
|
|
const bytes = [
|
|
(tmp[3] & 0xF0) | (tmp[0] & 0x0F),
|
|
(tmp[2] & 0xF0) | (tmp[1] & 0x0F),
|
|
(tmp[5] & 0xF0) | (tmp[6] & 0x0F),
|
|
(tmp[4] & 0xF0) | (tmp[7] & 0x0F),
|
|
(tmp[7] & 0xF0) | (tmp[4] & 0x0F),
|
|
(tmp[6] & 0xF0) | (tmp[5] & 0x0F),
|
|
(tmp[1] & 0xF0) | (tmp[2] & 0x0F),
|
|
(tmp[0] & 0xF0) | (tmp[3] & 0x0F)
|
|
];
|
|
|
|
bytes.forEach((val, i, arr) => {
|
|
arr[i] = val ^ xorKey.charCodeAt(i);
|
|
});
|
|
|
|
bytes[0] = ((bytes[0] << 1) & 0xFF) | (bytes[0] >> 7);
|
|
bytes[1] = ((bytes[1] << 7) & 0xFF) | (bytes[1] >> 1);
|
|
bytes[2] = ((bytes[2] << 2) & 0xFF) | (bytes[2] >> 6);
|
|
bytes[3] = ((bytes[3] << 8) & 0xFF) | (bytes[3] >> 0);
|
|
bytes[4] = ((bytes[4] << 3) & 0xFF) | (bytes[4] >> 5);
|
|
bytes[5] = ((bytes[5] << 6) & 0xFF) | (bytes[5] >> 2);
|
|
bytes[6] = ((bytes[6] << 4) & 0xFF) | (bytes[6] >> 4);
|
|
bytes[7] = ((bytes[7] << 5) & 0xFF) | (bytes[7] >> 3);
|
|
return bytes.map((val) => (val % 36).toString(36)).join("");
|
|
}
|
|
|
|
/* For Fujitsu-Siemens. 5x4 dicimal digits. new */
|
|
function fsi20DecNewKeygen(serial: string): string {
|
|
const fKeys = [
|
|
"4798156302", "7201593846", "5412367098", "6587249310",
|
|
"9137605284", "3974018625", "8052974163"
|
|
];
|
|
|
|
return [0, 2, 5, 11, 13, 15, 16].map((val, i) => {
|
|
let temp = parseInt(serial.charAt(val), 10);
|
|
return fKeys[i].charAt(temp);
|
|
}).join("");
|
|
}
|
|
|
|
export let fsiHexSolver = makeSolver({
|
|
name: "fsiHex",
|
|
description: "Fujitsu-Siemens hexdigits",
|
|
examples: ["DEADBEEF", "AAAA-BBBB-CCCC-DEAD-BEEF"],
|
|
inputValidator: (s) => /^([0-9ABCDEF]{20}|[0-9ABCDEF]{8})$/i.test(s),
|
|
fun: (code: string) => [fsiHexKeygen(code)]
|
|
});
|
|
|
|
export let fsi20DecNewSolver = makeSolver({
|
|
name: "fsiDecNew",
|
|
description: "Fujitsu-Siemens decimal new (5x4)",
|
|
examples: ["1234-4321-1234-4321-1234"],
|
|
inputValidator: (s) => /^\d{20}$/i.test(s),
|
|
fun: (code: string) => [fsi20DecNewKeygen(code)]
|
|
});
|
|
|
|
export let fsi20DecOldSolver = makeSolver({
|
|
name: "fsiDecOld",
|
|
description: "Fujitsu-Siemens decimal old (5x4)",
|
|
examples: ["1234-4321-1234-4321-1234"],
|
|
inputValidator: (s) => /^\d{20}$/i.test(s),
|
|
fun: (code: string) => [fsi20DecOldKeygen(code)]
|
|
});
|
|
|
|
export let fsi24DecSolver = makeSolver({
|
|
name: "fsi24Dec",
|
|
description: "Fujitsu-Siemens decimal old (6x4)",
|
|
examples: ["8F16-1234-4321-1234-4321-1234"],
|
|
inputValidator: (s) => /^[0-9ABCDEF]{4}\d{20}$/i.test(s),
|
|
fun: (code: string) => [fsi24DecKeygen(code)]
|
|
});
|