initial commit
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
.history
|
||||
node_modules/
|
||||
27
filter.ts
Normal file
27
filter.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import fs from "node:fs";
|
||||
|
||||
const base = "3961023";
|
||||
|
||||
const INPUT_FILE_NAME = `output_${base}.json`;
|
||||
const OUTPUT_FILE_NAME = `mapped_output_${base}.json`;
|
||||
|
||||
const writeToFile = (data: object) => {
|
||||
fs.writeFileSync(OUTPUT_FILE_NAME, JSON.stringify(data, undefined, 2));
|
||||
};
|
||||
|
||||
(() => {
|
||||
const existingData = fs.readFileSync(INPUT_FILE_NAME);
|
||||
const existingDataMapped = JSON.parse(existingData.toString()) as [string, string][];
|
||||
|
||||
const formatted = existingDataMapped.reduce((acc, [idCode, value]) => ({
|
||||
...acc,
|
||||
...(value === "INVALID" ? {} : {
|
||||
[idCode]: (() => {
|
||||
const nameStartIdx = value.indexOf(": ") + 2;
|
||||
const lastCommaIdx = value.lastIndexOf(",");
|
||||
return value.substring(nameStartIdx, lastCommaIdx);
|
||||
})(),
|
||||
})
|
||||
}), {});
|
||||
writeToFile(formatted);
|
||||
})();
|
||||
75
index.ts
Normal file
75
index.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import fs from "node:fs";
|
||||
|
||||
const base = "3961023";
|
||||
|
||||
const FILE_NAME = `output_${base}.json`;
|
||||
|
||||
const sleep = (timeout: number) => new Promise((res, rej) => {
|
||||
setTimeout(() => {
|
||||
res("ok");
|
||||
}, timeout);
|
||||
});
|
||||
|
||||
(async () => {
|
||||
const { default: Isikukood } = require("./isikukood.js");
|
||||
|
||||
const MAX = 10000;
|
||||
let valid = [];
|
||||
for (let i = 0; i <= MAX; i += 1) {
|
||||
const current = i.toString().padStart(4, "0");
|
||||
const full = base + current;
|
||||
const isValid = new Isikukood(full).validate();
|
||||
if (!isValid) {
|
||||
continue;
|
||||
}
|
||||
valid.push(full);
|
||||
}
|
||||
|
||||
const existingList: [string, string][] = [];
|
||||
try {
|
||||
const existingData = fs.readFileSync(FILE_NAME);
|
||||
const existingDataMapped = JSON.parse(existingData.toString()) as [string, string][];
|
||||
existingDataMapped.forEach((data) => existingList.push(data))
|
||||
} catch {}
|
||||
|
||||
const responses = existingList;
|
||||
const writeToFile = () => {
|
||||
fs.writeFileSync(FILE_NAME, JSON.stringify(responses, undefined, 2));
|
||||
};
|
||||
|
||||
const sleepBetweenSuccesses = async () => {
|
||||
console.debug("Got success response, sleeping...");
|
||||
await sleep(2_500);
|
||||
};
|
||||
const sleepBetweenErrors = async () => {
|
||||
console.debug("Got ratelimited, sleeping...");
|
||||
await sleep(7_500);
|
||||
};
|
||||
|
||||
for (let validEntry of valid) {
|
||||
if (existingList.find(([idCode]) => idCode === validEntry)) {
|
||||
console.debug("Skipping, already fetched data for idCode=" + validEntry);
|
||||
continue;
|
||||
}
|
||||
console.debug("Fetching data for idCode=" + validEntry);
|
||||
const response = await fetch("https://isikukood.ee/" + validEntry);
|
||||
const responseText = await response.text();
|
||||
if (responseText.includes("No scanning allowed, try again later.")) {
|
||||
await sleepBetweenErrors();
|
||||
} else {
|
||||
if (responseText.startsWith("N/A")) {
|
||||
console.debug("No person exists with idCode=" + validEntry);
|
||||
responses.push([validEntry, "INVALID"] as [string, string]);
|
||||
} else {
|
||||
responses.push([
|
||||
validEntry,
|
||||
responseText.substring(0, responseText.indexOf("\n\n"))
|
||||
] as [string, string]);
|
||||
}
|
||||
writeToFile();
|
||||
await sleepBetweenSuccesses();
|
||||
}
|
||||
}
|
||||
|
||||
console.debug("Writing results to file");
|
||||
})();
|
||||
194
isikukood.js
Normal file
194
isikukood.js
Normal file
@@ -0,0 +1,194 @@
|
||||
"use strict";
|
||||
module.exports = (() => {
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var isikukood_exports = {};
|
||||
__export(isikukood_exports, {
|
||||
Gender: () => Gender,
|
||||
default: () => Isikukood
|
||||
});
|
||||
class Isikukood {
|
||||
constructor(c) {
|
||||
this._code = String(c);
|
||||
}
|
||||
get code() {
|
||||
return this._code;
|
||||
}
|
||||
set code(c) {
|
||||
this._code = String(c);
|
||||
}
|
||||
getControlNumber(code = "") {
|
||||
if (!code) {
|
||||
code = this.code;
|
||||
}
|
||||
const mul1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 1];
|
||||
const mul2 = [3, 4, 5, 6, 7, 8, 9, 1, 2, 3];
|
||||
let controlNum = 0;
|
||||
let total = 0;
|
||||
for (let i = 0; i < 10; ++i) {
|
||||
total += Number(code.charAt(i)) * mul1[i];
|
||||
}
|
||||
controlNum = total % 11;
|
||||
total = 0;
|
||||
if (controlNum === 10) {
|
||||
for (let i = 0; i < 10; ++i) {
|
||||
total += Number(code.charAt(i)) * mul2[i];
|
||||
}
|
||||
controlNum = total % 11;
|
||||
if (controlNum === 10) {
|
||||
controlNum = 0;
|
||||
}
|
||||
}
|
||||
return controlNum;
|
||||
}
|
||||
validate() {
|
||||
if (this.code.charAt(0) === "0") {
|
||||
return false;
|
||||
}
|
||||
if (this.code.length !== 11) {
|
||||
return false;
|
||||
}
|
||||
const control = this.getControlNumber();
|
||||
if (control !== Number(this.code.charAt(10))) {
|
||||
return false;
|
||||
}
|
||||
const year = Number(this.code.substring(1, 3));
|
||||
const month = Number(this.code.substring(3, 5));
|
||||
const day = Number(this.code.substring(5, 7));
|
||||
const birthDate = this.getBirthday();
|
||||
return year === birthDate.getFullYear() % 100 && birthDate.getMonth() + 1 === month && day === birthDate.getDate();
|
||||
}
|
||||
getGender() {
|
||||
const genderNum = this.code.charAt(0);
|
||||
let retval;
|
||||
switch (genderNum) {
|
||||
case "1":
|
||||
case "3":
|
||||
case "5":
|
||||
retval = Gender.MALE;
|
||||
break;
|
||||
case "2":
|
||||
case "4":
|
||||
case "6":
|
||||
retval = Gender.FEMALE;
|
||||
break;
|
||||
default:
|
||||
retval = Gender.UNKNOWN;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
getAge() {
|
||||
return Math.floor((Date.now() - this.getBirthday().getTime()) / (86400 * 1e3) / 365.25);
|
||||
}
|
||||
getBirthday() {
|
||||
let year = Number(this.code.substring(1, 3));
|
||||
const month = Number(this.code.substring(3, 5).replace(/^0/, "")) - 1;
|
||||
const day = Number(this.code.substring(5, 7).replace(/^0/, ""));
|
||||
const firstNumber = this.code.charAt(0);
|
||||
for (let i = 1, j = 1800; i <= 8; i += 2, j += 100) {
|
||||
if ([i, i + 1].map(String).includes(firstNumber)) {
|
||||
year += j;
|
||||
}
|
||||
}
|
||||
return new Date(year, month, day);
|
||||
}
|
||||
parse() {
|
||||
return Isikukood.parse(this.code);
|
||||
}
|
||||
static parse(code) {
|
||||
const ik = new this(code);
|
||||
const data = {
|
||||
gender: ik.getGender(),
|
||||
birthDay: ik.getBirthday(),
|
||||
age: ik.getAge()
|
||||
};
|
||||
return data;
|
||||
}
|
||||
static generate(params = {}) {
|
||||
let y;
|
||||
let m;
|
||||
let d;
|
||||
const gender = params.gender || (Math.round(Math.random()) === 0 ? Gender.MALE : Gender.FEMALE);
|
||||
let personalId = "";
|
||||
const hospitals = [
|
||||
"00",
|
||||
"01",
|
||||
"02",
|
||||
"22",
|
||||
"27",
|
||||
"37",
|
||||
"42",
|
||||
"47",
|
||||
"49",
|
||||
"52",
|
||||
"57",
|
||||
"60",
|
||||
"65",
|
||||
"70",
|
||||
"95"
|
||||
];
|
||||
if (![Gender.MALE, Gender.FEMALE].includes(gender)) {
|
||||
return "";
|
||||
}
|
||||
if (params.birthYear) {
|
||||
y = params.birthYear;
|
||||
} else {
|
||||
y = Math.round(Math.random() * 100 + 1900 + (new Date().getFullYear() - 2e3));
|
||||
}
|
||||
if (params.birthMonth) {
|
||||
m = params.birthMonth;
|
||||
} else {
|
||||
m = Math.floor(Math.random() * 12) + 1;
|
||||
}
|
||||
if (params.birthDay) {
|
||||
d = params.birthDay;
|
||||
} else {
|
||||
const daysInMonth = new Date(y, m, 0).getDate();
|
||||
d = Math.floor(Math.random() * daysInMonth) + 1;
|
||||
}
|
||||
for (let i = 1800, j = 2; i <= 2100; i += 100, j += 2) {
|
||||
if (y >= i && y < i + 100) {
|
||||
switch (gender) {
|
||||
case Gender.MALE:
|
||||
personalId += String(j - 1);
|
||||
break;
|
||||
case Gender.FEMALE:
|
||||
personalId += String(j);
|
||||
break;
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
personalId += String(y).substring(2, 4);
|
||||
personalId += String(m).length === 1 ? `0${m}` : `${m}`;
|
||||
personalId += String(d).length === 1 ? `0${d}` : `${d}`;
|
||||
personalId += hospitals[Math.floor(Math.random() * hospitals.length)];
|
||||
personalId += String(Math.floor(Math.random() * 10));
|
||||
personalId += String(this.prototype.getControlNumber(personalId));
|
||||
return personalId;
|
||||
}
|
||||
}
|
||||
var Gender = /* @__PURE__ */ ((Gender2) => {
|
||||
Gender2["MALE"] = "male";
|
||||
Gender2["FEMALE"] = "female";
|
||||
Gender2["UNKNOWN"] = "unknown";
|
||||
return Gender2;
|
||||
})(Gender || {});
|
||||
return __toCommonJS(isikukood_exports);
|
||||
})();
|
||||
22
mapped_output.json
Normal file
22
mapped_output.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"45407170039": "RANDMA,SILVIA",
|
||||
"45407170061": "PUHACHOVA,TETIANA",
|
||||
"45407170165": "BRETT,NADEŽDA",
|
||||
"45407170213": "RUMJANTSEVA,ALEKSANDRA",
|
||||
"45407170224": "KHOTEEVA,OLGA",
|
||||
"45407170235": "TÕŠTŠUK,VALENTINA",
|
||||
"45407170257": "TEETLOK,GALINA",
|
||||
"45407172218": "SOINI,MAIRE",
|
||||
"45407172230": "TREIAL,LIIDIA",
|
||||
"45407172719": "GUSSAROVA-ŠLENDUHHOVA,KIRIAKIA",
|
||||
"45407172727": "KRUUS,AILI",
|
||||
"45407172229": "TIHHOMIROVA,SVETLANA",
|
||||
"45407174212": "DEMTŠENKO,LIIDIA",
|
||||
"45407174223": "HOLTER,ENE",
|
||||
"45407174713": "MÄGER,LEA",
|
||||
"45407174910": "JÕGI,KIRSTI",
|
||||
"45407175220": "RÄSTA,ELJU",
|
||||
"45407175231": "VESKI,LEELO",
|
||||
"45407176021": "LEHESMETS,TIIA",
|
||||
"45407176511": "VIHROVA,LJUDMILLA"
|
||||
}
|
||||
24
mapped_output_3961023.json
Normal file
24
mapped_output_3961023.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"39610230054": "DRAHUN,ANDREI",
|
||||
"39610230065": "RAKOTONIRINA,PIERRE ANDRIANJOHARY",
|
||||
"39610230087": "TURNER,RYNE MICHAEL",
|
||||
"39610230098": "STOCHITA,VLAD-TEODOR",
|
||||
"39610230108": "JGUIRIM,ZIED",
|
||||
"39610230130": "LOPES DE OLIVEIRA SANTOS,JOSUÉ",
|
||||
"39610230228": "KRJUKOV,DMITRI",
|
||||
"39610230250": "KRUTTO,CHRISTOPHER",
|
||||
"39610230261": "GAVALJAN,ERIK",
|
||||
"39610230827": "ROOTS,KRISTER",
|
||||
"39610230849": "HEINLAID,RIHO",
|
||||
"39610230851": "GURINOVITŠ,KIRILL",
|
||||
"39610230882": "SOKOLOV,SEMJON",
|
||||
"39610230903": "UDSO,KARLI",
|
||||
"39610231410": "MILLER,PÄRTEL",
|
||||
"39610232015": "REINAUS,PRIIT",
|
||||
"39610232767": "PIATKOWSKI,JULIUS",
|
||||
"39610232789": "KÄÄR,KEVIN",
|
||||
"39610233720": "KEBA,MAKSIM",
|
||||
"39610233731": "NIKONOV,ALEKSEI",
|
||||
"39610235213": "PÕLDOJA,JOEL",
|
||||
"39610235714": "JAKOVLEV,ROMAN"
|
||||
}
|
||||
3982
output.json
Normal file
3982
output.json
Normal file
File diff suppressed because it is too large
Load Diff
3878
output_3961023.json
Normal file
3878
output_3961023.json
Normal file
File diff suppressed because it is too large
Load Diff
19
package.json
Normal file
19
package.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "personal-code-finder",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.ts",
|
||||
"scripts": {
|
||||
"start": "ts-node --transpile-only index.ts",
|
||||
"filter": "ts-node --transpile-only filter.ts"
|
||||
},
|
||||
"author": "",
|
||||
"license": "UNLICENSED",
|
||||
"dependencies": {
|
||||
"@types/express": "4.17.21",
|
||||
"@types/node": "20.12.2",
|
||||
"isikukood": "3.1.4",
|
||||
"ts-node": "10.9.2",
|
||||
"typescript": "5.4.3"
|
||||
}
|
||||
}
|
||||
10
tsconfig.json
Normal file
10
tsconfig.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2016",
|
||||
"module": "commonjs",
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"skipLibCheck": true
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user