南非身份证号码验证



我已经对此进行了研究,但我使用的代码似乎都不起作用。南非身份证号码包含出生日期和性别。我想要的只是它提取该信息并在将他们的 ID 号输入输入字段时进行验证,以角度

我尝试使用我目前刚刚将其修改为打字稿的 javascript 代码。我没有收到任何错误,但它根本没有验证。

ts

this.registerForm = this.formBuilder.group({
confirm: ['', [Validators.required, Validators.email]],
};
validateRSAidnumber(idnumber) {
console.log('idnumber', idnumber);

let invalid = 0;

// check that value submitted is a number
if (isNaN(idnumber)) {
invalid++;
}

// check length of 13 digits
if (idnumber.length !== 13) {
invalid++;
}

// check that YYMMDD group is a valid date
const yy = idnumber.substring(0, 2);
const mm = idnumber.substring(2, 4);
const dd = idnumber.substring(4, 6);

const dob = new Date(yy, (mm - 1), dd);

// check values - add one to month because Date() uses 0-11 for months
if (!(((dob.getFullYear() + '').substring(2, 4) === yy) && (dob.getMonth() === mm - 1) && (dob.getDate() === dd))) {
invalid++;
}

// evaluate GSSS group for gender and sequence 
const gender = parseInt(idnumber.substring(6, 10), 10) > 5000 ? 'M' : 'F';

// ensure third to last digit is a 1 or a 0
if (idnumber.substring(10, 11) > 1) {
invalid++;
}

// ensure second to last digit is a 8 or a 9
if (idnumber.substring(11, 12) < 8) {
invalid++;
}

// calculate check bit (Z) using the Luhn algorithm
let ncheck = 0;
let beven = false;

for (let c = idnumber.length - 1; c >= 0; c--) {
const cdigit = idnumber.charAt(c);
let ndigit = parseInt(cdigit, 10);

if (beven) {
if ((ndigit *= 2) > 9) ndigit -= 9;
}

ncheck += ndigit;
beven = !beven;
}

if ((ncheck % 10) !== 0) {
invalid++;
}

return !invalid;
}


// convenience getter for easy access to form fields
get f() { return this.registerForm.controls; }
get isEmailMismatch() { return this.registerForm.getError('emailMismatch'); }

onSubmit() {
console.log('buttoj');
this.submitted = true;

this.userService.user.user.email = this.email;
this.userService.user.user.first_name = this.firstName;
this.userService.user.user.last_name = this.lastName;
this.userService.user.user.id_number = this.idNumber;
this.userService.user.user.password = this.password;
this.userService.user.user.phone = '0' + this.contactNumber.toString();
this.userService.user.user.id_number = this.idNumber.toString();
this.registerUser();
this.validateRSAidnumber(this.idNumber);
}

存储在南非身份证号码中的信息(例如8801235111088):

  • 数字 1 和 2 = 出生年份(例如 1988 年)
  • 数字 3 和 4 = 出生月份(例如 01/1 月)
  • 数字 5 和 6 = 出生日期(例如第 23 天)
  • 数字 7 到 10 用于定义性别(女性 = 0 到 4999;公头 = 5000 到 9999)(例如 5111 = 公头)
  • 数字 11 用于对您的公民身份进行分类(SA 公民 = 0;非南非公民 = 1)
  • 直到 1980 年代,数字 12 一直用于对种族进行分类
  • 数字 13 最后一个用作校验和,以确定 ID 号是否有效

以下是从任何南非身份证号码中提取信息的 Python 脚本:

Id = str(input("Please enter your South African Identity Number(ID): "))
#Id = "8801235111088"
#Date of birth
year = int(Id[0:2])
month = Id[2:4]
day = Id[4:6]
if year >= 50:
print("Date of birth is: ", day, month, "19" + str(year) )
if year < 50:
print("Date of birth is: " , day, month, "20" + str(year))
#gender
gender = int(Id[6:10])
if 0000 <= gender <= 4999:
print("Gender is : female")
if 5000 <= gender <= 9999:
print("Gender is: male")

#Citizen status
citizen = int(Id[10])
if citizen == 0:
print("You are a South African citizen")
if citizen == 1:
print("You are not a South African citizen")

我在角度表单验证中使用了 id 验证服务。不过,您可以在任何地方使用它。 一段时间以来,它在我的应用程序中运行良好。

idValidation.service.ts

export class IdValidationService {
constructor() {}
// going to accept ID as string to account for ID starting with 0
public isValid(id: string): boolean {
if (this.tryParseInt(id) === null) {
return false;
}
const idArray = this.toNumberArray(id);
if (idArray.length !== 13) {
return false;
}
if (!this.isValidDOB(id)) {
return false;
}
return this.validateId(idArray);
}
private isValidDOB(id: string): boolean {
const month = this.tryParseInt(id.substring(2, 4));
const day = this.tryParseInt(id.substring(4, 6));
// Validate month and day
if (
month < 1 ||
month > 12 ||
month == null ||
day < 1 ||
day > 31 ||
day == null
) {
return false;
}
//  Apr, Jun, Sep, Nov must not have more than 30 days
if (
(month === 4 || month === 6 || month === 9 || month === 11) &&
day > 30
) {
return false;
}
// Feb must not have more than 29 days
if (month === 2 && day > 29) {
return false;
}
// If Feb and day is 29, make sure is leap year
if (month === 2 && day === 29) {
let year = this.tryParseInt(id.substring(0, 2));
const currentYearTwoDigit = new Date().getFullYear() % 100;
year += year > currentYearTwoDigit ? 1900 : 2000;
// Check if is leap year
if (year % 400 === 0 || (year % 4 === 0 && year % 100 !== 0)) {
return true;
}
return false;
}
return true;
}
private toNumberArray(id: string): number[] {
return id.split('').map((num) => Number(num));
}
private tryParseInt(value: string, defaultValue = null): number {
const parsedValue = parseInt(value, 10);
if (isNaN(parsedValue)) {
return defaultValue;
}
return parsedValue;
}
private validateId(idArray: number[]): boolean {
// get check digit (last digit of id)
const checkDigit = idArray[12];
// get list of odd values except check digit
const oddValueArray = this.getOddValueArray(idArray);
// add odd values together
const oddValueSum = this.getSumOfNumberArray(oddValueArray);
// get list of even values
const evenValueArray = this.getEvenValueArray(idArray);
// concat even values into one number
let concatedEvenValues = this.concatNumberArray(evenValueArray);
// multiple concated even numbers value by 2
concatedEvenValues = concatedEvenValues * 2;
// get list of values in new concated even number's value
const concatedEvenValuesArray = this.toNumberArray(
String(concatedEvenValues)
);
// add list of concated even number values together
const sumOfConcatedEvenValues = this.getSumOfNumberArray(
concatedEvenValuesArray
);
// add odd value sum and concated even number sum together
const sumofOddAndEven = oddValueSum + sumOfConcatedEvenValues;
// convert the above sum into a list of values
const sumOfOddAndEvenArray = this.toNumberArray(String(sumofOddAndEven));
// get last digit of above value
const lastDigit = sumOfOddAndEvenArray[sumOfOddAndEvenArray.length - 1];
// get verifyCheckDigit which is 10 minus the above last digit
// (I am using %10 to ensure that 10-0 = 0, because if 10-0 = 10 compare digits will return false)
let verifyCheckDigit = (10 - lastDigit) % 10;
// if verifyCheckDigit has two digits, get the last digit
if (verifyCheckDigit > 9) {
verifyCheckDigit = this.toNumberArray(String(verifyCheckDigit)).pop();
}
// compare check digits and return true or false
return this.compareCheckDigits(checkDigit, verifyCheckDigit);
}
private getSumOfNumberArray(numberArray: number[]): number {
let sum = 0;
for (let i = 0; i < numberArray.length; i++) {
sum = sum + numberArray[i];
}
return sum;
}
private getOddValueArray(idArray: number[]): number[] {
const oddArray = [];
oddArray.push(idArray[0]);
oddArray.push(idArray[2]);
oddArray.push(idArray[4]);
oddArray.push(idArray[6]);
oddArray.push(idArray[8]);
oddArray.push(idArray[10]);
return oddArray;
}
private getEvenValueArray(idArray: number[]): number[] {
const evenArray = [];
evenArray.push(idArray[1]);
evenArray.push(idArray[3]);
evenArray.push(idArray[5]);
evenArray.push(idArray[7]);
evenArray.push(idArray[9]);
evenArray.push(idArray[11]);
return evenArray;
}
private concatNumberArray(numberArray: number[]): number {
return Number(numberArray.join(''));
}
private compareCheckDigits(
checkDigit: number,
verifyCheckDigit: number
): boolean {
if (verifyCheckDigit === checkDigit) {
return true;
}
return false;
}
}

最新更新