Split code into modules and add gulpfile
This commit is contained in:
1 parent
c66c0a9d74
commit
1ae71673d8
17 files changed
+579
-434
No files matched your search
+23
@@ -0,0 +1,23 @@
|
||||
var gulp = require("gulp");
|
||||
var ts = require("gulp-typescript");
|
||||
var tslint = require("gulp-tslint");
|
||||
var jasmine = require("gulp-jasmine");
|
||||
var tsProject = ts.createProject("tsconfig.json");
|
||||
|
||||
gulp.task("build", function() {
|
||||
return tsProject.src()
|
||||
.pipe(tsProject())
|
||||
.js.pipe(gulp.dest("dist"));
|
||||
});
|
||||
|
||||
gulp.task('test', ['build'], function() {
|
||||
return gulp.src("dist/*.spec.js").pipe(jasmine());
|
||||
});
|
||||
|
||||
gulp.task('tslint', function() {
|
||||
return tsProject.src()
|
||||
.pipe(tslint({"formatter": "verbose"}))
|
||||
.pipe(tslint.report());
|
||||
});
|
||||
|
||||
gulp.task('default', ['tslint', 'build', 'test'])
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "pwgen-for-bios",
|
||||
"version": "2.0.0",
|
||||
"description": "Password generator for BIOS",
|
||||
"main": "decrypt_bios.js",
|
||||
"dependencies": {
|
||||
"@types/jasmine": "^2.8.3",
|
||||
"gulp-jasmine": "^3.0.0",
|
||||
"typescript": "^2.6.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"gulp": "^3.9.1",
|
||||
"gulp-typescript": "^3.2.3",
|
||||
"typescript": "^2.6.2"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/bacher09/pwgen-for-bios.git"
|
||||
},
|
||||
"keywords": [
|
||||
"bios",
|
||||
"keygen",
|
||||
"password"
|
||||
],
|
||||
"scripts": {
|
||||
"gulp": "gulp"
|
||||
},
|
||||
"author": "Slava Bacherikov",
|
||||
"license": "GPL-3.0",
|
||||
"bugs": {
|
||||
"url": "https://github.com/bacher09/pwgen-for-bios/issues"
|
||||
},
|
||||
"homepage": "https://github.com/bacher09/pwgen-for-bios#readme"
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
var bios = require('../dist/decrypt_bios.js');
|
||||
|
||||
describe("Decrypt BIOS", function() {
|
||||
it("Sony key for 1234567 is 9648669", function() {
|
||||
expect(bios.Sony.solve("1234567")).toEqual(["9648669"]);
|
||||
});
|
||||
|
||||
it("Sony input validation", function() {
|
||||
expect(bios.Sony.check("1234")).toBe(false);
|
||||
expect(bios.Sony.check("1234567")).toBe(true);
|
||||
expect(bios.Sony.check("0123456")).toBe(true);
|
||||
expect(bios.Sony.check("123o567")).toBe(false);
|
||||
expect(bios.Sony.check("1234567D")).toBe(false);
|
||||
});
|
||||
|
||||
it("Samsung key for 07088120410C0000 is 12345", function() {
|
||||
expect(bios.Samsung.solve("07088120410C0000")).toEqual(["12345"]);
|
||||
});
|
||||
|
||||
it("Samsung input validation", function() {
|
||||
expect(bios.Samsung.check("07088120410C0000")).toBe(true);
|
||||
expect(bios.Samsung.check("07088120410C000000")).toBe(false);
|
||||
expect(bios.Samsung.check("07088120410C000O")).toBe(false);
|
||||
expect(bios.Samsung.check("07088120410C")).toBe(true);
|
||||
expect(bios.Samsung.check("07088120410C00")).toBe(true);
|
||||
expect(bios.Samsung.check("0123456")).toBe(false);
|
||||
expect(bios.Samsung.check("07088a20410C00")).toBe(true);
|
||||
});
|
||||
|
||||
it("HPMini key for CNU1234ABC is e9l37fvcpe", function() {
|
||||
expect(bios.HPMini.solve("CNU1234ABC")).toEqual(["e9l37fvcpe"]);
|
||||
});
|
||||
|
||||
it("HPMini input validation", function() {
|
||||
expect(bios.HPMini.check("CNU1234ABC")).toBe(true);
|
||||
expect(bios.HPMini.check("CNU1234ABCV")).toBe(false);
|
||||
expect(bios.HPMini.check("CNU12$4ABC")).toBe(false);
|
||||
expect(bios.HPMini.check("CNU12п4ABC")).toBe(false);
|
||||
});
|
||||
|
||||
it("Insyde key for 03133610 is 12891236", function() {
|
||||
expect(bios.Insyde.solve("03133610")).toEqual(["12891236"]);
|
||||
});
|
||||
|
||||
it("Insyde input validation", function() {
|
||||
expect(bios.Insyde.check("12345678")).toBe(true);
|
||||
expect(bios.Insyde.check("123456789")).toBe(false);
|
||||
expect(bios.Insyde.check("1234o678")).toBe(false);
|
||||
expect(bios.Insyde.check("12345678d")).toBe(false);
|
||||
});
|
||||
|
||||
it("FSI 20 dec key for 1234-4321-1234-4321-1234 is 7122790 or 10cphf0b", function() {
|
||||
expect(bios.FSI20DecOld.solve(bios.CleanSerial("1234-4321-1234-4321-1234")))
|
||||
.toEqual(["7122790", "10cphf0b"]);
|
||||
|
||||
expect(bios.FSI20DecOld.solve(bios.CleanSerial("1234-4321-1234-4321-1236")))
|
||||
.toEqual(["7122790", "100phf0b"]);
|
||||
})
|
||||
|
||||
it("FSI 20 hex key for AAAA-BBBB-CCCC-DEAD-BEEF is 64830592", function() {
|
||||
expect(bios.FSI20Hex.solve(bios.CleanSerial("AAAA-BBBB-CCCC-DEAD-BEEF")))
|
||||
.toEqual(["64830592"]);
|
||||
});
|
||||
});
|
||||
@@ -1,367 +0,0 @@
|
||||
type Predicate<T> = (val: T) => boolean;
|
||||
type Tuple<A, B> = [A, B];
|
||||
type BIOSSolver = (val: string) => string[];
|
||||
|
||||
export const enum BIOSModels {
|
||||
Sony = 1,
|
||||
Samsung,
|
||||
Phoenix,
|
||||
HPCompaq,
|
||||
FSIPhoenix,
|
||||
FSILPhoenix,
|
||||
FSIPPhoenix,
|
||||
FSISPhoenix,
|
||||
FSIXPhoenix,
|
||||
Insyde,
|
||||
HPMini
|
||||
};
|
||||
|
||||
interface BIOSDecoder {
|
||||
model: BIOSModels;
|
||||
name: string;
|
||||
description?: string;
|
||||
examples?: string[];
|
||||
check: Predicate<string>;
|
||||
solve: BIOSSolver;
|
||||
}
|
||||
|
||||
type FindResult = Tuple<string[], BIOSDecoder>;
|
||||
|
||||
namespace Utils {
|
||||
/* May be need add 51, 52 and 53 symbol */
|
||||
const keyboardDict: {[key: number]: string} = {
|
||||
2: "1", 3: "2", 4: "3", 5: "4", 6: "5", 7: "6", 8: "7", 9: "8",
|
||||
10: "9", 11: "0", 16: "q", 17: "w", 18: "e", 19: "r", 20: "t", 21: "y",
|
||||
22: "u", 23: "i", 24: "o", 25: "p", 30: "a", 31: "s", 32: "d", 33: "f",
|
||||
34: "g", 35: "h", 36: "j", 37: "k", 38: "l", 44: "z", 45: "x", 46: "c",
|
||||
47: "v", 48: "b", 49: "n", 50: "m"
|
||||
};
|
||||
/* Decode Keyboard code to Ascii symbol */
|
||||
export function keyboardEncToAscii(inKey: number[]): string {
|
||||
let out = "";
|
||||
for (let i = 0; i < inKey.length; i++) {
|
||||
if (inKey[i] === 0) return out;
|
||||
if (inKey[i] in keyboardDict) {
|
||||
out += keyboardDict[inKey[i]];
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return password for old sony laptops
|
||||
* password 7 digit number like 1234567 */
|
||||
function SonySolver(serial: string): string {
|
||||
if (serial.length !== 7) {
|
||||
return null;
|
||||
}
|
||||
const table = "0987654321876543210976543210982109876543109876543221098765436543210987";
|
||||
let code = "";
|
||||
for (let i = 0; i < serial.length; i++) {
|
||||
code += table.charAt(parseInt(serial.charAt(i), 10) + 10 * i);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
/* Return password for samsung laptops
|
||||
* 12 or 18 hexhecimal digits like 07088120410C0000 */
|
||||
function SamsungSolver(serial: string): string[] {
|
||||
|
||||
const rotationMatrix1 = [
|
||||
7, 1, 5, 3, 0, 6, 2, 5, 2, 3, 0, 6, 1, 7, 6, 1, 5, 2, 7, 1, 0, 3, 7,
|
||||
6, 1, 0, 5, 2, 1, 5, 7, 3, 2, 0, 6
|
||||
];
|
||||
const rotationMatrix2 = [
|
||||
1, 6, 2, 5, 7, 3, 0, 7, 1, 6, 2, 5, 0, 3, 0, 6, 5, 1, 1, 7, 2, 5, 2,
|
||||
3, 7, 6, 2, 1, 3, 7, 6, 5, 0, 1, 7
|
||||
];
|
||||
|
||||
function keyToAscii(inKey: number[]): string {
|
||||
let out = "";
|
||||
for (let i = 0; i < inKey.length; i++) {
|
||||
if (inKey[i] === 0) return out;
|
||||
if (inKey[i] < 32 || inKey[i] > 127) return undefined;
|
||||
out += String.fromCharCode(inKey[i]);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
function decryptHash(hash: number[], key: number, rotationMatrix: number[]) {
|
||||
let outhash: number[] = [];
|
||||
for (let i = 0; i < hash.length; i++) {
|
||||
let val = ((hash[i] << (rotationMatrix[7 * key + i])) & 0xFF) |
|
||||
(hash[i] >> (8 - rotationMatrix[7 * key + i]));
|
||||
outhash.push(val);
|
||||
}
|
||||
return outhash;
|
||||
}
|
||||
|
||||
let hash: number[] = [];
|
||||
for (let i = 1; i < Math.floor(serial.length / 2); i++) {
|
||||
let val = parseInt(serial.charAt(2 * i) + serial.charAt(2 * i + 1), 16);
|
||||
hash.push(val);
|
||||
}
|
||||
let key = parseInt(serial.substring(0, 2), 16) % 5;
|
||||
|
||||
let calcScanCodePwd = (matrix: number[]) =>
|
||||
Utils.keyboardEncToAscii(decryptHash(hash, key, matrix));
|
||||
|
||||
let scanCodePassword = calcScanCodePwd(rotationMatrix1);
|
||||
if (scanCodePassword === "") {
|
||||
scanCodePassword = calcScanCodePwd(rotationMatrix2);
|
||||
}
|
||||
|
||||
let asciiPassword1 = keyToAscii(decryptHash(hash, key, rotationMatrix1));
|
||||
let asciiPassword2 = keyToAscii(decryptHash(hash, key, rotationMatrix2));
|
||||
|
||||
// TODO: This might require polyfil
|
||||
return [scanCodePassword, asciiPassword1, asciiPassword2].
|
||||
filter(code => code ? true : false);
|
||||
}
|
||||
|
||||
/* For HP/Compaq Netbooks. 10 chars */
|
||||
function HPMiniSolver(serial: string): string[] {
|
||||
const table1: {[key: string]: string} = {
|
||||
"1": "3", "0": "1", "3": "F", "2": "7", "5": "Q", "4": "V",
|
||||
"7": "X", "6": "G", "9": "O", "8": "U", "a": "C", "c": "E",
|
||||
"b": "P", "e": "M", "d": "T", "g": "H", "f": "8", "i": "Y",
|
||||
"h": "Z", "k": "S", "j": "W", "m": "4", "l": "K", "o": "J",
|
||||
"n": "9", "q": "5", "p": "2", "s": "N", "r": "B", "u": "L",
|
||||
"t": "A", "w": "D", "v": "6", "y": "I", "x": "4", "z": "0"
|
||||
};
|
||||
|
||||
const table2: {[key: string]: string} = {
|
||||
"1": "3", "0": "1", "3": "F", "2": "7", "5": "Q", "4": "V",
|
||||
"7": "X", "6": "G", "9": "O", "8": "U", "a": "C", "c": "E",
|
||||
"b": "P", "e": "M", "d": "T", "g": "H", "f": "8", "i": "Y",
|
||||
"h": "Z", "k": "S", "j": "W", "m": "4", "l": "K", "o": "J",
|
||||
"n": "9", "q": "5", "p": "2", "s": "N", "r": "B", "u": "L",
|
||||
"t": "A", "w": "D", "v": "6", "y": "I", "x": "R", "z": "0"
|
||||
};
|
||||
|
||||
let password1 = "";
|
||||
let password2 = "";
|
||||
serial = serial.toLowerCase();
|
||||
for (let i = 0; i < serial.length; i++) {
|
||||
password1 += table1[serial.charAt(i)];
|
||||
password2 += table2[serial.charAt(i)];
|
||||
}
|
||||
if (password1 === password2) {
|
||||
return [password1.toLowerCase()];
|
||||
} else {
|
||||
return [password1.toLowerCase(), password2.toLowerCase()];
|
||||
}
|
||||
}
|
||||
|
||||
/* Maybe need fixing for browsers where numbers is 32-bits */
|
||||
/* Some Acer, HP laptops. 8 digit */
|
||||
function InsydeSolver(serial: string): string[] {
|
||||
const salt = "Iou|hj&Z";
|
||||
let password = "";
|
||||
let b = 0;
|
||||
let a = 0;
|
||||
for (let i = 0; i < 8; i++) {
|
||||
b = salt.charCodeAt(i) ^ serial.charCodeAt(i);
|
||||
a = b;
|
||||
// a = (a * 0x66666667) >> 32;
|
||||
a = (a * 0x66666667);
|
||||
a = Math.floor(a / Math.pow(2, 32));
|
||||
a = (a >> 2) | (a & 0xC0);
|
||||
if (a & 0x80000000) {
|
||||
a++;
|
||||
}
|
||||
a *= 10;
|
||||
password += (b - a).toString();
|
||||
}
|
||||
return [password];
|
||||
}
|
||||
|
||||
/* For Fujinsu-Siemens. 5x4 dicimal digits */
|
||||
function FSI20DecOldSolver(serial: string): string {
|
||||
function swap<T> (arr: T[], i1: number, i2: number): void {
|
||||
let temp = arr[i1];
|
||||
arr[i1] = arr[i2];
|
||||
arr[i2] = temp;
|
||||
};
|
||||
// op_arr - array with that operations do, ar1,ar2 - numbers */
|
||||
function interleave(op_arr: number[], ar1: number[], ar2: number[]) {
|
||||
let arr = op_arr.slice(0); // copy array
|
||||
arr[ar1[0]] = ((op_arr[ar2[0]] >> 4) | (op_arr[ar2[3]] << 4)) & 0xFF;
|
||||
arr[ar1[1]] = ((op_arr[ar2[0]] & 0x0F) | (op_arr[ar2[3]] & 0xF0));
|
||||
arr[ar1[2]] = ((op_arr[ar2[1]] >> 4) | (op_arr[ar2[2]] << 4) & 0xFF);
|
||||
arr[ar1[3]] = (op_arr[ar2[1]] & 0x0F) | (op_arr[ar2[2]] & 0xF0);
|
||||
return arr;
|
||||
}
|
||||
|
||||
function codeToBytes(code: string): number[] {
|
||||
let 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)
|
||||
];
|
||||
return numbers.reduce((acc, val) => {
|
||||
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
|
||||
bytes.forEach((val, i, arr) => {
|
||||
arr[i] = val ^ XORkey.charCodeAt(i);
|
||||
});
|
||||
// swap two bytes
|
||||
swap(bytes, 2, 6);
|
||||
swap(bytes, 3, 7);
|
||||
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);
|
||||
// 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 decryptCode_old(codeToBytes(serial));
|
||||
}
|
||||
|
||||
/* For Fujinsu-Siemens. 5x4 dicimal digits. new */
|
||||
function FSI20DecNewSolver(serial: string): string {
|
||||
const f_keys = [
|
||||
"4798156302", "7201593846", "5412367098", "6587249310",
|
||||
"9137605284", "3974018625", "8052974163"
|
||||
];
|
||||
|
||||
return [0, 2, 5, 11, 13, 15, 16].map((val, i, arr) => {
|
||||
let temp = parseInt(serial.charAt(val), 10);
|
||||
return f_keys[i].charAt(temp);
|
||||
}).join("");
|
||||
}
|
||||
|
||||
/* For Fujinsu-Siemens. 8 or 5x4 hexadecimal digits. */
|
||||
function FSI20HexSolver(serial: string): string {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
const table = generateCRC16Table();
|
||||
return hashToString(calculateHash(serial.slice(0, 4), table)) +
|
||||
hashToString(calculateHash(serial.slice(4, 8), table));
|
||||
}
|
||||
|
||||
export let CleanSerial = (serial: string) => serial.trim().replace(/-/gi, "");
|
||||
|
||||
export let Sony: BIOSDecoder = {
|
||||
model: BIOSModels.Sony,
|
||||
name: "Sony",
|
||||
examples: ["1234567"],
|
||||
check: (s) => /^\d{7}$/i.test(s),
|
||||
solve: (s) => {
|
||||
let res = SonySolver(s);
|
||||
return res ? [res] : [];
|
||||
}
|
||||
};
|
||||
|
||||
export let Samsung: BIOSDecoder = {
|
||||
model: BIOSModels.Samsung,
|
||||
name: "Samsung",
|
||||
examples: ["07088120410C0000"],
|
||||
check: (s) => /^[0-9ABCDEF]+$/i.test(s) && (
|
||||
s.length === 12 || s.length === 14 || s.length === 16
|
||||
),
|
||||
solve: SamsungSolver
|
||||
};
|
||||
|
||||
export let HPMini: BIOSDecoder = {
|
||||
model: BIOSModels.HPMini,
|
||||
name: "HPMini",
|
||||
examples: ["CNU1234ABC"],
|
||||
check: (s) => /^[0-9A-Z]{10}$/i.test(s),
|
||||
solve: HPMiniSolver
|
||||
};
|
||||
|
||||
export let Insyde: BIOSDecoder = {
|
||||
model: BIOSModels.Insyde,
|
||||
name: "Insyde H2O",
|
||||
examples: ["03133610"],
|
||||
check: (s) => /^\d{8}$/i.test(s),
|
||||
solve: InsydeSolver
|
||||
};
|
||||
|
||||
export let FSI20DecOld: BIOSDecoder = {
|
||||
model: BIOSModels.FSIPhoenix,
|
||||
name: "Fujitsu-Siemens decimal",
|
||||
examples: ["1234-4321-1234-4321-1234"],
|
||||
check: (s) => /^\d{20}$/i.test(s),
|
||||
solve: (serial) => [FSI20DecNewSolver(serial), FSI20DecOldSolver(serial)]
|
||||
};
|
||||
|
||||
export let FSI20Hex: BIOSDecoder = {
|
||||
model: BIOSModels.FSILPhoenix,
|
||||
name: "Fujitsu-Siemens hexdigits",
|
||||
examples: ["AAAA-BBBB-CCCC-DEAD-BEEF"],
|
||||
check: (s) => /^[0-9ABCDEF]{20}$/i.test(s),
|
||||
solve: (serial) => [FSI20HexSolver(serial)]
|
||||
};
|
||||
|
||||
export let Decoders: BIOSDecoder[] = [
|
||||
Sony, Samsung, HPMini, Insyde, FSI20DecOld
|
||||
];
|
||||
|
||||
export function runDecoder(serial: string, decoder: BIOSDecoder): string[] {
|
||||
return decoder.check(serial) ? decoder.solve(serial) : [];
|
||||
}
|
||||
|
||||
export function runDecoders(serial: string, decoders: BIOSDecoder[]): FindResult[] {
|
||||
return decoders.map((dec: BIOSDecoder): FindResult =>
|
||||
[runDecoder(serial, dec), dec]).filter(res => res[0].length > 0);
|
||||
}
|
||||
|
||||
export let findPassword = (serial: string) =>
|
||||
runDecoders(CleanSerial(serial), Decoders);
|
||||
@@ -0,0 +1,45 @@
|
||||
import { fsi20DecNewSolver, fsi20DecOldSolver, fsi20HexSolver } from "./fsi";
|
||||
|
||||
describe("Test Fujitsu-Siemens 5x4 hexadecimal BIOS", () => {
|
||||
it("FSI key for 1234-4321-1234-4321-1234 is 35682708", () => {
|
||||
expect(fsi20HexSolver("1234-4321-1234-4321-1234")).toEqual(["35683789"]);
|
||||
});
|
||||
it("FSI key for AAAA-BBBB-CCCC-DEAD-BEEF is 64830592", () => {
|
||||
expect(fsi20HexSolver("AAAA-BBBB-CCCC-DEAD-BEEF")).toEqual(["64830592"]);
|
||||
expect(fsi20HexSolver("AAAABBBBCCCCDEADBEEF")).toEqual(["64830592"]);
|
||||
});
|
||||
it("test invalid keys", () => {
|
||||
expect(fsi20HexSolver("AAAA-BBBB-CCCC-DEAD-CODE")).toEqual([]);
|
||||
expect(fsi20HexSolver("AAAA-BBBB-CCCC-DEAD-BEEF-12")).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Test Fujitsu-Siemens 5x4 decimal new", () => {
|
||||
it("FSI key for 1234-4321-1234-4321-1234 is 7122790", () => {
|
||||
expect(fsi20DecNewSolver("1234-4321-1234-4321-1234")).toEqual(["7122790"]);
|
||||
});
|
||||
|
||||
it("FSI key for 7234-4321-1234-4321-1234 is 3122790", () => {
|
||||
expect(fsi20DecNewSolver("7234-4321-1234-4321-1234")).toEqual(["3122790"]);
|
||||
});
|
||||
|
||||
it("test invalid keys", () => {
|
||||
expect(fsi20DecNewSolver("1234-4321-1234-4321-1234-1")).toEqual([]);
|
||||
expect(fsi20DecNewSolver("1234-4321-1234-4321-BEEF")).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Test Fujitsu-Siemens 5x4 decimal old", () => {
|
||||
it("FSI key for 1234-4321-1234-4321-1234 is 10cphf0b", () => {
|
||||
expect(fsi20DecOldSolver("1234-4321-1234-4321-1234")).toEqual(["10cphf0b"]);
|
||||
});
|
||||
|
||||
it("FSI key for 7234-4321-1234-4321-1234 is 10cphf0b", () => {
|
||||
expect(fsi20DecOldSolver("7234-4321-1234-4321-1234")).toEqual(["90ldhf0b"]);
|
||||
});
|
||||
|
||||
it("test invalid keys", () => {
|
||||
expect(fsi20DecOldSolver("1234-4321-1234-4321-1234-1")).toEqual([]);
|
||||
expect(fsi20DecOldSolver("1234-4321-1234-4321-BEEF")).toEqual([]);
|
||||
});
|
||||
});
|
||||
+144
@@ -0,0 +1,144 @@
|
||||
import { makeSolver } from "./utils";
|
||||
/* tslint:disable:no-bitwise */
|
||||
|
||||
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 Fujinsu-Siemens. 8 or 5x4 hexadecimal digits. */
|
||||
function fsi20HexKeygen(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));
|
||||
}
|
||||
|
||||
/* For Fujinsu-Siemens. 5x4 dicimal digits */
|
||||
function fsi20DecOldKeygen(serial: string): string {
|
||||
|
||||
function swap<T>(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
|
||||
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 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
|
||||
bytes.forEach((val, i, arr) => {
|
||||
arr[i] = val ^ xorKey.charCodeAt(i);
|
||||
});
|
||||
// swap two bytes
|
||||
swap(bytes, 2, 6);
|
||||
swap(bytes, 3, 7);
|
||||
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);
|
||||
// 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 decryptCode_old(codeToBytes(serial));
|
||||
}
|
||||
|
||||
/* For Fujinsu-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, arr) => {
|
||||
let temp = parseInt(serial.charAt(val), 10);
|
||||
return fKeys[i].charAt(temp);
|
||||
}).join("");
|
||||
}
|
||||
|
||||
export let fsi20HexSolver = makeSolver({
|
||||
name: "Fujitsu-Siemens hexdigits",
|
||||
examples: ["AAAA-BBBB-CCCC-DEAD-BEEF"],
|
||||
inputValidator: (s) => /^[0-9ABCDEF]{20}$/i.test(s),
|
||||
fun: (code: string) => [fsi20HexKeygen(code)]
|
||||
});
|
||||
|
||||
export let fsi20DecNewSolver = makeSolver({
|
||||
name: "Fujitsu-Siemens decimal new",
|
||||
examples: ["1234-4321-1234-4321-1234"],
|
||||
inputValidator: (s) => /^\d{20}$/i.test(s),
|
||||
fun: (code: string) => [fsi20DecNewKeygen(code)]
|
||||
});
|
||||
|
||||
export let fsi20DecOldSolver = makeSolver({
|
||||
name: "Fujitsu-Siemens decimal old",
|
||||
examples: ["1234-4321-1234-4321-1234"],
|
||||
inputValidator: (s) => /^\d{20}$/i.test(s),
|
||||
fun: (code: string) => [fsi20DecOldKeygen(code)]
|
||||
});
|
||||
@@ -0,0 +1,14 @@
|
||||
import { hpMiniSolver } from "./hpmini";
|
||||
|
||||
describe("Test HP Mini BIOS", () => {
|
||||
it("HPMini key for CNU1234ABC is e9l37fvcpe", () => {
|
||||
expect(hpMiniSolver("CNU1234ABC")).toEqual(["e9l37fvcpe"]);
|
||||
});
|
||||
it("HPMini key for CNU1234567 is e9l37fvqgx", () => {
|
||||
expect(hpMiniSolver("CNU1234567")).toEqual(["e9l37fvqgx"]);
|
||||
});
|
||||
it("test invalid keys", () => {
|
||||
expect(hpMiniSolver("CNU12345678")).toEqual([]);
|
||||
expect(hpMiniSolver("CNU1234")).toEqual([]);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
/* For HP/Compaq Netbooks. 10 chars */
|
||||
import { makeSolver } from "./utils";
|
||||
|
||||
const table1: {[key: string]: string} = {
|
||||
"1": "3", "0": "1", "3": "F", "2": "7", "5": "Q", "4": "V",
|
||||
"7": "X", "6": "G", "9": "O", "8": "U", "a": "C", "c": "E",
|
||||
"b": "P", "e": "M", "d": "T", "g": "H", "f": "8", "i": "Y",
|
||||
"h": "Z", "k": "S", "j": "W", "m": "4", "l": "K", "o": "J",
|
||||
"n": "9", "q": "5", "p": "2", "s": "N", "r": "B", "u": "L",
|
||||
"t": "A", "w": "D", "v": "6", "y": "I", "x": "4", "z": "0"
|
||||
};
|
||||
|
||||
const table2: {[key: string]: string} = {
|
||||
"1": "3", "0": "1", "3": "F", "2": "7", "5": "Q", "4": "V",
|
||||
"7": "X", "6": "G", "9": "O", "8": "U", "a": "C", "c": "E",
|
||||
"b": "P", "e": "M", "d": "T", "g": "H", "f": "8", "i": "Y",
|
||||
"h": "Z", "k": "S", "j": "W", "m": "4", "l": "K", "o": "J",
|
||||
"n": "9", "q": "5", "p": "2", "s": "N", "r": "B", "u": "L",
|
||||
"t": "A", "w": "D", "v": "6", "y": "I", "x": "R", "z": "0"
|
||||
};
|
||||
|
||||
function hpMiniKeygen(serial: string): string[] {
|
||||
|
||||
let password1 = "";
|
||||
let password2 = "";
|
||||
serial = serial.toLowerCase();
|
||||
for (let i = 0; i < serial.length; i++) {
|
||||
password1 += table1[serial.charAt(i)];
|
||||
password2 += table2[serial.charAt(i)];
|
||||
}
|
||||
if (password1 === password2) {
|
||||
return [password1.toLowerCase()];
|
||||
} else {
|
||||
return [password1.toLowerCase(), password2.toLowerCase()];
|
||||
}
|
||||
}
|
||||
|
||||
export let hpMiniSolver = makeSolver({
|
||||
name: "HPMini",
|
||||
examples: ["CNU1234ABC"],
|
||||
inputValidator: (s) => /^[0-9A-Z]{10}$/i.test(s),
|
||||
fun: hpMiniKeygen
|
||||
});
|
||||
@@ -0,0 +1,15 @@
|
||||
import { insydeSolver } from "./insyde";
|
||||
|
||||
describe("Insyde BIOS", () => {
|
||||
it("Insyde key for 03133610 is 12891236", () => {
|
||||
expect(insydeSolver("03133610")).toEqual(["12891236"]);
|
||||
});
|
||||
it("Insyde key for 12345678 is 03023278", () => {
|
||||
expect(insydeSolver("12345678")).toEqual(["03023278"]);
|
||||
});
|
||||
|
||||
it("test invalid keys", () => {
|
||||
expect(insydeSolver("123456789")).toEqual([]);
|
||||
expect(insydeSolver("1234567")).toEqual([]);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,32 @@
|
||||
/* Maybe need fixing for browsers where numbers is 32-bits */
|
||||
/* Some Acer, HP laptops. 8 digit */
|
||||
import { makeSolver } from "./utils";
|
||||
|
||||
/* tslint:disable:no-bitwise */
|
||||
function insydeKeygen(serial: string): string[] {
|
||||
const salt = "Iou|hj&Z";
|
||||
let password = "";
|
||||
let b = 0;
|
||||
let a = 0;
|
||||
for (let i = 0; i < 8; i++) {
|
||||
b = salt.charCodeAt(i) ^ serial.charCodeAt(i);
|
||||
a = b;
|
||||
// a = (a * 0x66666667) >> 32;
|
||||
a = (a * 0x66666667);
|
||||
a = Math.floor(a / Math.pow(2, 32));
|
||||
a = (a >> 2) | (a & 0xC0);
|
||||
if (a & 0x80000000) {
|
||||
a++;
|
||||
}
|
||||
a *= 10;
|
||||
password += (b - a).toString();
|
||||
}
|
||||
return [password];
|
||||
}
|
||||
|
||||
export let insydeSolver = makeSolver({
|
||||
name: "Insyde H2O",
|
||||
examples: ["03133610"],
|
||||
inputValidator: (s) => /^\d{8}$/i.test(s),
|
||||
fun: insydeKeygen
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
import { samsungSolver } from "./samsung";
|
||||
|
||||
describe("Test Samsung BIOS", () => {
|
||||
it("Samsung key for 07088120410C0000 is 12345", () => {
|
||||
expect(samsungSolver("07088120410C0000")).toEqual(["12345"]);
|
||||
});
|
||||
it("Samsung key for 07088120410C is 12345", () => {
|
||||
expect(samsungSolver("07088120410C")).toEqual(["12345"]);
|
||||
});
|
||||
|
||||
it("Samsung key for 1AA9CD4638C0186000 is 5728000", () => {
|
||||
expect(samsungSolver("1AA9CD4638C0186000")).toEqual(["5728000"]);
|
||||
});
|
||||
it("test invalid keys", () => {
|
||||
expect(samsungSolver("1AA9CD4638C01860Z0")).toEqual([]);
|
||||
expect(samsungSolver("1AA9CD4638C01860000")).toEqual([]);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,78 @@
|
||||
/* tslint:disable:no-bitwise */
|
||||
/* Return password for samsung laptops
|
||||
* 12 or 18 hexhecimal digits like 07088120410C0000
|
||||
*/
|
||||
|
||||
import { makeSolver } from "./utils";
|
||||
import { keyboardEncToAscii } from "./utils";
|
||||
|
||||
const rotationMatrix1 = [
|
||||
7, 1, 5, 3, 0, 6, 2, 5, 2, 3, 0, 6, 1, 7, 6, 1, 5, 2, 7, 1, 0, 3, 7,
|
||||
6, 1, 0, 5, 2, 1, 5, 7, 3, 2, 0, 6
|
||||
];
|
||||
const rotationMatrix2 = [
|
||||
1, 6, 2, 5, 7, 3, 0, 7, 1, 6, 2, 5, 0, 3, 0, 6, 5, 1, 1, 7, 2, 5, 2,
|
||||
3, 7, 6, 2, 1, 3, 7, 6, 5, 0, 1, 7
|
||||
];
|
||||
|
||||
function keyToAscii(intKeys: number[]): string | undefined {
|
||||
let out = "";
|
||||
|
||||
for (let intKey of intKeys) {
|
||||
if (intKey === 0) {
|
||||
return out;
|
||||
}
|
||||
if (intKey < 32 || intKey > 127) {
|
||||
return undefined;
|
||||
}
|
||||
out += String.fromCharCode(intKey);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
function decryptHash(hash: number[], key: number, rotationMatrix: number[]): number[] {
|
||||
let outhash: number[] = [];
|
||||
|
||||
for (let i = 0; i < hash.length; i++) {
|
||||
const val = ((hash[i] << (rotationMatrix[7 * key + i])) & 0xFF) |
|
||||
(hash[i] >> (8 - rotationMatrix[7 * key + i]));
|
||||
outhash.push(val);
|
||||
}
|
||||
|
||||
return outhash;
|
||||
}
|
||||
|
||||
function samsungKeygen(serial: string): string[] {
|
||||
let hash: number[] = [];
|
||||
|
||||
for (let i = 1; i < Math.floor(serial.length / 2); i++) {
|
||||
let val = parseInt(serial.charAt(2 * i) + serial.charAt(2 * i + 1), 16);
|
||||
hash.push(val);
|
||||
}
|
||||
let key = parseInt(serial.substring(0, 2), 16) % 5;
|
||||
|
||||
let calcScanCodePwd = (matrix: number[]) =>
|
||||
keyboardEncToAscii(decryptHash(hash, key, matrix));
|
||||
|
||||
let scanCodePassword = calcScanCodePwd(rotationMatrix1);
|
||||
if (scanCodePassword === "") {
|
||||
scanCodePassword = calcScanCodePwd(rotationMatrix2);
|
||||
}
|
||||
|
||||
const asciiPassword1 = keyToAscii(decryptHash(hash, key, rotationMatrix1));
|
||||
const asciiPassword2 = keyToAscii(decryptHash(hash, key, rotationMatrix2));
|
||||
|
||||
// TODO: This might require polyfil
|
||||
return [scanCodePassword, asciiPassword1, asciiPassword2].
|
||||
filter((code) => code ? true : false) as string[];
|
||||
}
|
||||
|
||||
export let samsungSolver = makeSolver({
|
||||
name: "Samsung",
|
||||
examples: ["07088120410C0000"],
|
||||
inputValidator: (s) => /^[0-9ABCDEF]+$/i.test(s) && (
|
||||
s.length === 12 || s.length === 14 || s.length === 16 || s.length === 18
|
||||
),
|
||||
fun: samsungKeygen
|
||||
});
|
||||
@@ -0,0 +1,11 @@
|
||||
import { sonySolver } from "./sony";
|
||||
|
||||
describe("Sony BIOS", () => {
|
||||
it("Sony key for 1234567 is 9648669", () => {
|
||||
expect(sonySolver("1234567")).toEqual(["9648669"]);
|
||||
});
|
||||
it("test invalid keys", () => {
|
||||
expect(sonySolver("123456789")).toEqual([]);
|
||||
expect(sonySolver("123")).toEqual([]);
|
||||
});
|
||||
});
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
import { makeSolver } from "./utils";
|
||||
/* Return password for old sony laptops
|
||||
* password 7 digit number like 1234567
|
||||
*/
|
||||
function sonyKeygen(serial: string): string {
|
||||
const table = "0987654321876543210976543210982109876543109876543221098765436543210987";
|
||||
let code: string = "";
|
||||
for (let i = 0; i < serial.length; i++) {
|
||||
code += table.charAt(parseInt(serial.charAt(i), 10) + 10 * i);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
export let sonySolver = makeSolver({
|
||||
name: "Sony",
|
||||
examples: ["1234567"],
|
||||
inputValidator: (s) => /^\d{7}$/i.test(s),
|
||||
fun: (code: string) => {
|
||||
let res = sonyKeygen(code);
|
||||
return res ? [res] : [];
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,76 @@
|
||||
export type Predicate<T> = (val: T) => boolean;
|
||||
export type SolverFunction = (val: string) => string[];
|
||||
|
||||
export interface SolverDescription {
|
||||
readonly name: string;
|
||||
readonly description?: string;
|
||||
readonly examples?: string[];
|
||||
fun: SolverFunction;
|
||||
inputValidator: Predicate<string>;
|
||||
}
|
||||
|
||||
export interface Solver {
|
||||
(code: string): string[];
|
||||
readonly biosName: string;
|
||||
readonly examples?: string[];
|
||||
readonly description?: string;
|
||||
validator(code: string): boolean;
|
||||
cleaner(code: string): string;
|
||||
keygen(code: string): string[];
|
||||
}
|
||||
|
||||
const keyboardDict: {[key: number]: string} = {
|
||||
2: "1", 3: "2", 4: "3", 5: "4", 6: "5", 7: "6", 8: "7", 9: "8",
|
||||
10: "9", 11: "0", 16: "q", 17: "w", 18: "e", 19: "r", 20: "t", 21: "y",
|
||||
22: "u", 23: "i", 24: "o", 25: "p", 30: "a", 31: "s", 32: "d", 33: "f",
|
||||
34: "g", 35: "h", 36: "j", 37: "k", 38: "l", 44: "z", 45: "x", 46: "c",
|
||||
47: "v", 48: "b", 49: "n", 50: "m"
|
||||
};
|
||||
|
||||
/* Decode Keyboard code to Ascii symbol */
|
||||
export function keyboardEncToAscii(inKey: number[]): string {
|
||||
let out = "";
|
||||
for (let key of inKey) {
|
||||
if (key === 0) {
|
||||
return out;
|
||||
}
|
||||
|
||||
if (key in keyboardDict) {
|
||||
out += keyboardDict[key];
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function cleanSerial(serial: string): string {
|
||||
return serial.trim().replace(/-/gi, "");
|
||||
}
|
||||
|
||||
export function makeSolver(description: SolverDescription): Solver {
|
||||
|
||||
let solver: any = (code: string) => {
|
||||
let cleanCode = cleanSerial(code);
|
||||
if (description.inputValidator(cleanCode)) {
|
||||
return description.fun(cleanCode);
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
solver.biosName = description.name;
|
||||
solver.validator = description.inputValidator;
|
||||
solver.cleaner = cleanSerial;
|
||||
solver.keygen = description.fun;
|
||||
|
||||
if (description.examples) {
|
||||
solver.examples = description.examples;
|
||||
}
|
||||
|
||||
if (description.description) {
|
||||
solver.description = description.description;
|
||||
}
|
||||
|
||||
return solver as Solver;
|
||||
}
|
||||
+4
-3
@@ -3,13 +3,14 @@
|
||||
"module": "commonjs",
|
||||
"target": "es3",
|
||||
"noImplicitAny": true,
|
||||
"sourceMap": false,
|
||||
"outDir": "javascript/"
|
||||
"strictNullChecks": true,
|
||||
"sourceMap": true,
|
||||
"outDir": "dist/"
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
],
|
||||
"files": [
|
||||
"src/decrypt_bios.ts"
|
||||
"src/*.ts"
|
||||
]
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"defaultSeverity": "error",
|
||||
"extends": [
|
||||
"tslint:recommended"
|
||||
],
|
||||
"jsRules": {},
|
||||
"rules": {
|
||||
"trailing-comma": [true, {"multiline": "never", "singleline": "never"}],
|
||||
"variable-name": [true, "ban-keywords", "check-format"],
|
||||
"prefer-const": false,
|
||||
"interface-name": [true, "never-prefix"],
|
||||
"object-literal-key-quotes": false,
|
||||
"object-literal-sort-keys": false,
|
||||
"no-namespace": false
|
||||
},
|
||||
"rulesDirectory": []
|
||||
}
|
||||
Reference in new issue
Block a user