diff --git a/src/keygen/fsi.spec.ts b/src/keygen/fsi.spec.ts index ca6d446..32c6aaa 100644 --- a/src/keygen/fsi.spec.ts +++ b/src/keygen/fsi.spec.ts @@ -1,4 +1,4 @@ -import { fsi20DecNewSolver, fsi20DecOldSolver, fsiHexSolver } from "./fsi"; +import { fsi20DecNewSolver, fsi20DecOldSolver, fsi24DecSolver, fsiHexSolver } from "./fsi"; describe("Test Fujitsu-Siemens 5x4 hexadecimal BIOS", () => { it("FSI key for 1234-4321-1234-4321-1234 is 35682708", () => { @@ -46,3 +46,20 @@ describe("Test Fujitsu-Siemens 5x4 decimal old", () => { expect(fsi20DecOldSolver("1234-4321-1234-4321-BEEF")).toEqual([]); }); }); + +describe("Test Fujitsu-Siemens 6x4 decimal", () => { + it("FSI key for 8F16-1234-4321-1234-4321-1234 is sjqtka8l", () => { + expect(fsi24DecSolver("8F16-1234-4321-1234-4321-1234")).toEqual(["sjqtka8l"]); + }); + + it("FSI key for 1234-7234-4321-1234-4321-1234 is smqtkaa5", () => { + expect(fsi24DecSolver("1234-7234-4321-1234-4321-1234")).toEqual(["smqtkaa5"]); + }); + + it("test invalid keys", () => { + expect(fsi24DecSolver("1234-4321-1234-4321-1234-1")).toEqual([]); + expect(fsi24DecSolver("1234-1234-4321-1234-4321-BEEF")).toEqual([]); + expect(fsi24DecSolver("F234-4321-1234-4321-1234-1234-1")).toEqual([]); + expect(fsi24DecSolver("1234-1234-4321-1234-4321-BEEF")).toEqual([]); + }); +}); diff --git a/src/keygen/fsi.ts b/src/keygen/fsi.ts index 6fcdccc..e184337 100644 --- a/src/keygen/fsi.ts +++ b/src/keygen/fsi.ts @@ -18,7 +18,7 @@ function generateCRC16Table(): number[] { const crc16Table = generateCRC16Table(); -/* For Fujinsu-Siemens. 8 or 5x4 hexadecimal digits. */ +/* For Fujitsu-Siemens. 8 or 5x4 hexadecimal digits. */ function fsiHexKeygen(serial: string): string { function hashToString(hash: number) { @@ -46,14 +46,24 @@ function fsiHexKeygen(serial: string): string { hashToString(calculateHash(serial.slice(4, 8), crc16Table)); } -/* For Fujinsu-Siemens. 5x4 dicimal digits */ +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 { - function swap(arr: T[], i1: number, i2: number): void { - const temp = arr[i1]; - arr[i1] = arr[i2]; - arr[i2] = temp; - } // opArr - array with that operations do, ar1,ar2 - numbers */ function interleave(opArr: number[], ar1: number[], ar2: number[]) { let arr = opArr.slice(0); // copy array @@ -64,21 +74,6 @@ function fsi20DecOldKeygen(serial: string): string { return arr; } - 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; - } - function decryptCode_old(bytes: number[]) { const xorKey = ":3-v@e4i"; // apply XOR key @@ -86,8 +81,8 @@ function fsi20DecOldKeygen(serial: string): string { arr[i] = val ^ xorKey.charCodeAt(i); }); // swap two bytes - swap(bytes, 2, 6); - swap(bytes, 3, 7); + [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 @@ -98,18 +93,43 @@ function fsi20DecOldKeygen(serial: string): string { 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); - // len(solution space) = 10 + 26 - bytes = bytes.map((b) => b % 36); - return bytes.map((sbyte) => (sbyte > 9 ) - ? String.fromCharCode("a".charCodeAt(0) + sbyte - 10) - : String.fromCharCode("0".charCodeAt(0) + sbyte) - ).join(""); + return bytes.map((b) => (b % 36).toString(36)).join(""); } return decryptCode_old(codeToBytes(serial)); } -/* For Fujinsu-Siemens. 5x4 dicimal digits. new */ +/* 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", @@ -132,7 +152,7 @@ export let fsiHexSolver = makeSolver({ export let fsi20DecNewSolver = makeSolver({ name: "fsiDecNew", - description: "Fujitsu-Siemens decimal new", + description: "Fujitsu-Siemens decimal new (5x4)", examples: ["1234-4321-1234-4321-1234"], inputValidator: (s) => /^\d{20}$/i.test(s), fun: (code: string) => [fsi20DecNewKeygen(code)] @@ -140,8 +160,16 @@ export let fsi20DecNewSolver = makeSolver({ export let fsi20DecOldSolver = makeSolver({ name: "fsiDecOld", - description: "Fujitsu-Siemens decimal old", + 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)] +}); diff --git a/src/keygen/index.ts b/src/keygen/index.ts index f8b247a..7e2adc8 100644 --- a/src/keygen/index.ts +++ b/src/keygen/index.ts @@ -1,7 +1,7 @@ import { monotonicTime } from "../polyfills/performancePolyfill"; import { asusSolver } from "./asus"; import { dellHddSolver, dellSolver, hddOldSolver } from "./dell"; -import { fsi20DecNewSolver, fsi20DecOldSolver, fsiHexSolver } from "./fsi"; +import { fsi20DecNewSolver, fsi20DecOldSolver, fsi24DecSolver, fsiHexSolver } from "./fsi"; import { hpMiniSolver } from "./hpmini"; import { insydeSolver } from "./insyde"; import { @@ -26,6 +26,7 @@ export const solvers: Solver[] = [ fsiHexSolver, fsi20DecNewSolver, fsi20DecOldSolver, + fsi24DecSolver, hpMiniSolver, insydeSolver, phoenixSolver,