8

I've researched this but none of the code I use seems to work. South African ID numbers contain date of birth and gender. All I want is it to pull in that information and verify it when their ID number is entered into an input field, preferably in jQuery or javascript

Any help is appreciated,

Dawid

Reinstate Monica Cellio
  • 25,975
  • 6
  • 51
  • 67
  • 2
    Or we should be S.Africans to know that or take some time to do researches... Isn't it much easier for us all that you provide more info? Help us to help you – Roko C. Buljan Nov 12 '12 at 13:12
  • Sorry Sorry, Very true... Heres the attempts http://daverussell.co.za/wordpress/2010/03/02/using-javascript-to-validate-south-african-id-numbers/ http://codereview.stackexchange.com/questions/12735/verifying-a-south-african-id Ive tryd a few others i cant find at the moment but... It basically needs to check if you have 13 numbers then use "http://en.wikipedia.org/wiki/Luhn_algorithm" to validate it. –  Nov 12 '12 at 13:23
  • Could you at least provide sample user input i.e. a valid SA ID number? – chridam Nov 12 '12 at 13:25
  • http://www.legalcity.net/Index.cfm?fuseaction=tools.idcheck <-- Exactly what im trying to accomplish –  Nov 12 '12 at 13:36

4 Answers4

11

You could use Koenyn's regex validation, not so sure how a single-digit number (0-9?) from the input represents the gender but basing on this tool you provided and David Russell's Using Javascript to validate South African ID Numbers, here's an untested attempt:

UPDATE 1: After following this thread, What is a South African ID number made up of?, I updated my implementation to include the gender and citizenship tests.

UPDATE 2: Forgot to wrap the month number increment id_month + 1 within the date string fullDate, updating solution with Dawid's fix.

HTML Markup:

<div id="error"></div>

<form id="idCheck">
    <p>Enter the ID Number: <input id="idnumber" /> </p>
    <p> <input type="submit" value="Check" /> </p>
</form>

<div id="result"> </div>

Javascript:

function Validate() {
    // first clear any left over error messages
    $('#error p').remove();

    // store the error div, to save typing
    var error = $('#error');

    var idNumber = $('#idnumber').val();


    // assume everything is correct and if it later turns out not to be, just set this to false
    var correct = true;

    //Ref: http://www.sadev.co.za/content/what-south-african-id-number-made
    // SA ID Number have to be 13 digits, so check the length
    if (idNumber.length != 13 || !isNumber(idNumber)) {
        error.append('<p>ID number does not appear to be authentic - input not a valid number</p>');
        correct = false;
    }

    // get first 6 digits as a valid date
    var tempDate = new Date(idNumber.substring(0, 2), idNumber.substring(2, 4) - 1, idNumber.substring(4, 6));

    var id_date = tempDate.getDate();
    var id_month = tempDate.getMonth();
    var id_year = tempDate.getFullYear();

    var fullDate = id_date + "-" + (id_month + 1) + "-" + id_year;

    if (!((tempDate.getYear() == idNumber.substring(0, 2)) && (id_month == idNumber.substring(2, 4) - 1) && (id_date == idNumber.substring(4, 6)))) {
        error.append('<p>ID number does not appear to be authentic - date part not valid</p>');
        correct = false;
    }

    // get the gender
    var genderCode = idNumber.substring(6, 10);
    var gender = parseInt(genderCode) < 5000 ? "Female" : "Male";

    // get country ID for citzenship
    var citzenship = parseInt(idNumber.substring(10, 11)) == 0 ? "Yes" : "No";

    // apply Luhn formula for check-digits
    var tempTotal = 0;
    var checkSum = 0;
    var multiplier = 1;
    for (var i = 0; i < 13; ++i) {
        tempTotal = parseInt(idNumber.charAt(i)) * multiplier;
        if (tempTotal > 9) {
            tempTotal = parseInt(tempTotal.toString().charAt(0)) + parseInt(tempTotal.toString().charAt(1));
        }
        checkSum = checkSum + tempTotal;
        multiplier = (multiplier % 2 == 0) ? 1 : 2;
    }
    if ((checkSum % 10) != 0) {
        error.append('<p>ID number does not appear to be authentic - check digit is not valid</p>');
        correct = false;
    };


    // if no error found, hide the error message
    if (correct) {
        error.css('display', 'none');

        // clear the result div
        $('#result').empty();
        // and put together a result message
        $('#result').append('<p>South African ID Number:   ' + idNumber + '</p><p>Birth Date:   ' + fullDate + '</p><p>Gender:  ' + gender + '</p><p>SA Citizen:  ' + citzenship + '</p>');
    }
    // otherwise, show the error
    else {
        error.css('display', 'block');
    }

    return false;
}

function isNumber(n) {
    return !isNaN(parseFloat(n)) && isFinite(n);
}

$('#idCheck').submit(Validate);

DEMO: http://jsfiddle.net/chridam/VSKNx/

chridam
  • 100,957
  • 23
  • 236
  • 235
  • You are most welcome! If I get the chance it would be nice to implement the elegant check-digit code by @st-boost in this [solution](http://codereview.stackexchange.com/a/12762) – chridam Nov 15 '12 at 20:03
  • Hey Man, I Found a slight problem... the month it returns.. It seems that it subtracts one from the month and then later tries to add it, unfortunately instead of getting 7+1 = 8, its giving 7+1=71.. I'm still playing around with it but hey any help would be great. –  Dec 04 '12 at 09:15
  • sorry fixed with - var fullDate = id_date + "-" + (id_month + 1) + "-" + id_year; –  Dec 04 '12 at 09:18
  • Aaah, cheers for that. Had forgotten to wrap the month number increment within the date string, just like how you fixed. Will update my solution with your fix, thanks. – chridam Dec 04 '12 at 09:29
  • 2
    Im using your code but running into an issues when adding a id number 010101.... it gives the year of birth 1901 instead of 2001 any work around for this? – Louwki Apr 26 '16 at 05:56
  • @Louwki Thanks for pointing this out, can you possibly create a new question for this issue so that I may help you out when I get the chance? – chridam Sep 07 '16 at 07:30
7

this is the validation regex we us at our company:

string IdExpression = @"(?<Year>[0-9][0-9])(?<Month>([0][1-9])|([1][0-2]))(?<Day>([0-2][0-9])|([3][0-1]))(?<Gender>[0-9])(?<Series>[0-9]{3})(?<Citizenship>[0-9])(?<Uniform>[0-9])(?<Control>[0-9])";

as far as using regex, it's really simple http://www.w3schools.com/jsref/jsref_obj_regexp.asp

Koenyn
  • 694
  • 4
  • 16
  • So...a two-digit number for year, month and day, then a single-digit number (0-9?) for gender (how does that work?), three numbers for series (what's a 'series' in context?), and single-digits for citizenship, uniform and control? – David Thomas Nov 12 '12 at 13:35
  • series is the order that the person was registered for that day. not sure about the others. – Koenyn Nov 12 '12 at 13:39
  • Exactly what im attempting ---> http://www.legalcity.net/Index.cfm?fuseaction=tools.idcheck –  Nov 12 '12 at 13:39
  • Thanks, @Koenyn, your answer helped me, however, I noticed that your regex allows a birth day of 00. I updated the section of the regex slightly: (?([0][1-9])|([1-2][0-9])|([3][0-1])) – Philip Trenwith Aug 11 '20 at 10:02
1

There is a jQuery plugin that you can use. Check it out at http://www.verifyid.co.za/jqueryid

6dev6il6
  • 767
  • 2
  • 15
  • 34
0

So there is an issue where if the ID number starts with 0 it gives the year of birth 1901 instead of 2001. @louwki mentioned it in his comment

I'm using your code but running into an issues when adding a id number 010101.... it gives the year of birth 1901 instead of 2001 any work around for this?

I have a work around assuming that there is no one older than a 100 years still alive who wants to get their date

// get first 6 digits as a valid date
var tempDate = new Date(idNumber.substring(0, 2), idNumber.substring(2, 4) - 1, idNumber.substring(4, 6));

var id_date = tempDate.getDate();
var id_month = tempDate.getMonth();
var id_year = tempDate.getFullYear();

 // Add a 100 years to the current year if older than 100 years
 if(id_year < (new Date()).getFullYear() - 100){     
   id_year+= 100
 }

var fullDate = id_date + "-" + id_month + 1 + "-" + id_year;

DEMO: http://jsfiddle.net/dupies/5fwxvu6d/3/

Ruan
  • 3,969
  • 10
  • 60
  • 87