#region Copyright (c) 2006 Synerics Business Solutions /* (c) 2006 Synerics Business Solutions code@synerics.com www.synerics.com This software is provided 'as-is', without any warranty. Permission is granted to anyone to use this software for any purpose. This notice may not be removed from any source distribution; if you are using this software in a product, this notice should be included in materials distributed with your product. */ #endregion using System; using System.Text; using System.Text.RegularExpressions; namespace Foundation.Utils { /// /// Validates a South African identity number. /// public class IDValidator { // constants const int VALID_LENGTH = 13; const int CONTROL_DIGIT_LOCATION = 12; const int CONTROL_DIGIT_CHECK_VALUE = 10; const int CONTROL_DIGIT_CHECK_EXCEPTION_VALUE = 9; const string REGEX_ID_PATTERN = "(?[0-9][0-9])(?([0][1-9])|([1][0-2]))(?([0-2][0-9])|([3][0-1]))(?[0-9])(?[0-9]{3})(?[0-9])(?[0-9])(?[0-9])"; const bool VALID = true; const bool INVALID = false; // member variables private string id; // constructor public IDValidator(string id_) { id = id_; } public int GetAge() { if (isValid()) { DateTime birthDate = DateTime.ParseExact(id.Substring(0,2) + "/" + id.Substring(2,2) + "/" + id.Substring(4,2), "yy/MM/dd", System.Globalization.CultureInfo.InvariantCulture); int years = DateTime.Now.Year - birthDate.Year; if (years < 0) { birthDate = DateTime.ParseExact("19" + id.Substring(0, 2) + "/" + id.Substring(2, 2) + "/" + id.Substring(4, 2), "yyyy/MM/dd", System.Globalization.CultureInfo.InvariantCulture); years = DateTime.Now.Year - birthDate.Year; } if (DateTime.Now.Month < birthDate.Month || (DateTime.Now.Month == birthDate.Month && DateTime.Now.Day < birthDate.Day)) years--; return years; } else { throw new Exception("Invalid ID"); } } // SA citizen check public bool IsSACitizen() { if (isValid()) { if (int.Parse(id.Substring(10,1)) == 0) { return true; } else { return false; } } else { throw new Exception("Invalid ID"); } } // gender check public bool IsFemale() { if (isValid()) { if (int.Parse(id.Substring(6,1)) < 5) { return true; } else { return false; } } else { throw new Exception("Invalid ID"); } } // get date of birth public string GetDateOfBirth() { if (isValid()) { DateTime date = DateTime.ParseExact(id.Substring(0,2) + "/" + id.Substring(2,2) + "/" + id.Substring(4,2), "yy/MM/dd", System.Globalization.CultureInfo.InvariantCulture); int years = DateTime.Now.Year - date.Year; if (years < 0) { date = DateTime.ParseExact("19" + id.Substring(0, 2) + "/" + id.Substring(2, 2) + "/" + id.Substring(4, 2), "yyyy/MM/dd", System.Globalization.CultureInfo.InvariantCulture); } return date.ToShortDateString(); } else { throw new Exception("Invalid ID"); } } public DateTime GetDateOfBirthAsDateTime() { if (isValid()) { DateTime date = DateTime.ParseExact(id.Substring(0,2) + "/" + id.Substring(2,2) + "/" + id.Substring(4,2), "yy/MM/dd", System.Globalization.CultureInfo.InvariantCulture); int years = DateTime.Now.Year - date.Year; if (years < 0) { date = DateTime.ParseExact("19" + id.Substring(0, 2) + "/" + id.Substring(2, 2) + "/" + id.Substring(4, 2), "yyyy/MM/dd", System.Globalization.CultureInfo.InvariantCulture); } return date; } else { throw new Exception("Invalid ID"); } } // check whether ID number is valid public bool isValid() { // assume that the id number is invalid bool isValidPattern = false; bool isValidLength = false; bool isValidControlDigit = false; // check length if (id.Length == VALID_LENGTH) { isValidLength = true; } // match regex pattern, only if length is valid if (isValidLength) { Regex idPattern = new Regex(REGEX_ID_PATTERN); if (idPattern.IsMatch(id)) { //00 will slip through the regex and checksum if (id.Substring(2, 2) != "00" && id.Substring(4, 2) != "00") { isValidPattern = true; } } } // check control digit, only if previous validations passed if (isValidLength && isValidPattern) { int a = 0; int b = 0; int c = 0; int cDigit = -1; int tmp = 0; StringBuilder even = new StringBuilder(); string evenResult = null; // sum odd digits for (int i=0; i CONTROL_DIGIT_CHECK_EXCEPTION_VALUE) { if (0 == int.Parse(id[CONTROL_DIGIT_LOCATION].ToString())) { isValidControlDigit = true; } } } } // final check if (isValidLength && isValidPattern && isValidControlDigit) { return VALID; } else { return INVALID; } } } }