belarus-personal-number-validator
Version:
Validator for belarussian passport personal number
57 lines (56 loc) • 2.08 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.validate = void 0;
function checkValidSymbols(symbols) {
if (typeof symbols !== 'string') {
const error = {
tag: 'Err',
err: "Personal number must be string" /* MustBeString */,
};
return error;
}
if (symbols.length !== 14) {
const error = {
tag: 'Err',
err: "Personal number must contain 14 symbols" /* MustContain14symbols */,
};
return error;
}
if (/^[0-9A-Z]*$/.test(symbols) === false) {
const error = {
tag: 'Err',
err: "Personal number must contain only numbers and uppercase Latin letters" /* OnlyNumbersAndUppercaseLatin */,
};
return error;
}
const ok = { tag: 'Ok', ok: 'Symbols are valid' };
return ok;
}
function getEncodedNumber(char, index) {
const encodedNumber = Number.isInteger(+char)
? +char
: char.charCodeAt(0) - 65 + 10;
return encodedNumber * [7, 3, 1][index % 3];
}
function getCalculatedControlNumber(personalNumber) {
return (Array.from(personalNumber.slice(0, -1)).reduce((accum, curr, index) => accum + getEncodedNumber(curr, index), 0) % 10);
}
function compareControlNumbers(x, y) {
const ok = { tag: 'Ok', ok: 'Control numbers are equal' };
const err = {
tag: 'Err',
err: "Control numbers are not equal" /* ControlNumbersAreNotEqual */,
};
return x === y ? ok : err;
}
function validate(personalNumber) {
const validateSymbolResult = checkValidSymbols(personalNumber);
if (validateSymbolResult.tag === 'Err') {
return { valid: false, error: validateSymbolResult.err };
}
const compareResult = compareControlNumbers(getCalculatedControlNumber(personalNumber), +personalNumber.slice(-1));
return compareResult.tag === 'Ok'
? { valid: true, error: null }
: { valid: false, error: compareResult.err };
}
exports.validate = validate;