south-african-id-validator
Version:
Dead simple validator for South African ID numbers
67 lines (51 loc) • 2.03 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.parseDOB = exports.parseCitizenship = exports.parseGender = exports.validateIdNumber = void 0;
const validateIdNumber = idNumber => {
const ex = /^(((\d{2}((0[13578]|1[02])(0[1-9]|[12]\d|3[01])|(0[13456789]|1[012])(0[1-9]|[12]\d|30)|02(0[1-9]|1\d|2[0-8])))|([02468][048]|[13579][26])0229))(( |-)(\d{4})( |-)(\d{3})|(\d{7}))/;
if (ex.test(idNumber) === false) {
return {
valid: false
};
}
return {
valid: true,
gender: parseGender(idNumber),
DOB: parseDOB(idNumber),
isCitizen: parseCitizenship(idNumber)
};
};
exports.validateIdNumber = validateIdNumber;
const parseGender = idNumber => {
const genderCode = idNumber.substring(6, 10);
const gender = Number(genderCode) < 5000 ? 'female' : 'male';
return gender;
};
exports.parseGender = parseGender;
const parseCitizenship = idNumber => {
const citizenshipCode = idNumber.substring(10, 11);
const isCitizen = Number(citizenshipCode) === 0;
return isCitizen;
};
exports.parseCitizenship = parseCitizenship;
const parseDOB = idNumber => {
const currentYear = new Date().getFullYear();
const currentCentury = Math.floor(currentYear / 100) * 100;
const currentMonth = new Date().getMonth();
const currentDay = new Date().getDay();
let yearPart = currentCentury + parseInt(idNumber.substring(0, 2), 10);
const monthPart = parseInt(idNumber.substring(2, 4), 10) - 1;
const dayPart = parseInt(idNumber.substring(4, 6), 10);
const eligibleYear = currentYear - 16;
if (yearPart > eligibleYear || yearPart === eligibleYear && (monthPart > currentMonth || monthPart === currentMonth && dayPart > currentDay)) {
yearPart -= 100;
}
const dateOfBirth = new Date(yearPart, monthPart, dayPart);
if (!dateOfBirth || dateOfBirth.getFullYear() !== yearPart || dateOfBirth.getMonth() !== monthPart || dateOfBirth.getDate() !== dayPart) {
return undefined;
}
return dateOfBirth;
};
exports.parseDOB = parseDOB;