1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
global.saIdParser = factory();
}(this, (function () {
'use strict';
return {
parse: parse,
validate: validate,
parseDateOfBirth: parseDateOfBirth,
parseIsMale: parseIsMale,
parseIsFemale: parseIsFemale,
parseIsSouthAfricanCitizen: parseIsSouthAfricanCitizen
};
function parse(idNumber) {
var isValid = validate(idNumber);
if (!isValid) {
return {
isValid: false
};
}
return {
isValid: isValid,
dateOfBirth: parseDateOfBirth(idNumber),
isMale: parseIsMale(idNumber),
isFemale: parseIsFemale(idNumber),
isSouthAfricanCitizen: parseIsSouthAfricanCitizen(idNumber)
};
}
function validate(idNumber) {
if (!regexpValidate(idNumber) || !datePartValidate(idNumber) || !controlDigitValidate(idNumber)) {
return false;
}
return true;
}
function regexpValidate(idNumber) {
if (typeof(idNumber) !== 'string') {
return false;
}
var regexp = /^[0-9]{13}$/;
return regexp.test(idNumber);
}
function datePartValidate(idNumber) {
var dateOfBirth = parseDateOfBirth(idNumber);
return !!dateOfBirth;
}
function controlDigitValidate(idNumber) {
var checkDigit = parseInt(idNumber[12], 10);
var oddDigitsSum = 0;
for (var i = 0; i < idNumber.length - 1; i+=2) {
oddDigitsSum += parseInt(idNumber[i], 10);
}
var evenDigits = '';
for (var j = 1; j < idNumber.length - 1; j+=2) {
evenDigits += idNumber[j];
}
evenDigits = parseInt(evenDigits, 10);
evenDigits *= 2;
evenDigits = '' + evenDigits;
var sumOfEvenDigits = 0;
for (var k = 0; k < evenDigits.length; k++) {
sumOfEvenDigits += parseInt(evenDigits[k], 10);
}
var total = sumOfEvenDigits + oddDigitsSum;
var computedCheckDigit = 10 - (total % 10);
if (computedCheckDigit === 10) {
computedCheckDigit = 0;
}
return computedCheckDigit === checkDigit;
}
function parseDateOfBirth(idNumber) {
if (!regexpValidate(idNumber)) {
return undefined;
}
//get year, and assume century
var currentYear = new Date().getFullYear();
var currentCentury = Math.floor(currentYear/100)*100;
var yearPart = currentCentury + parseInt(idNumber.substring(0,2), 10);
if (yearPart > currentYear) {
yearPart -= 100; //must be last century
}
//In Javascript, Jan=0. In ID Numbers, Jan=1.
var monthPart = parseInt(idNumber.substring(2,4), 10)-1;
var dayPart = parseInt(idNumber.substring(4,6), 10);
var dateOfBirth = new Date(yearPart, monthPart, dayPart);
//validate that date is in a valid range by making sure that it wasn't 'corrected' during construction
if (!dateOfBirth || dateOfBirth.getFullYear() !== yearPart || dateOfBirth.getMonth() !== monthPart || dateOfBirth.getDate() !== dayPart) {
return undefined;
}
return dateOfBirth;
}
function parseIsMale(idNumber) {
return !parseIsFemale(idNumber);
}
function parseIsFemale(idNumber) {
if (!regexpValidate(idNumber)) {
return undefined;
}
return parseInt(idNumber[6], 10) <= 4;
}
function parseIsSouthAfricanCitizen(idNumber) {
if (!regexpValidate(idNumber)) {
return undefined;
}
return parseInt(idNumber[10], 10) === 0;
}
})));
|