Last active
November 30, 2021 09:45
-
-
Save Dissimilis/22ee7b33bdc79e24a0b8e5fbf9c2fc0a to your computer and use it in GitHub Desktop.
Lithuanian national id validator in C# .NET. Lietuviško asmens kodo validavimas.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Fastest c# nationalid validator with birthdate extraction | |
public static class NationalIdValidator | |
{ | |
public static bool ValidateNationalId(string nationalId, out DateTime? birthdate) | |
{ | |
birthdate = null; | |
if (nationalId.Length != 11 || !long.TryParse(nationalId, out long nid)) | |
return false; | |
return ValidateNationalId(nid, out birthdate); | |
} | |
public static bool ValidateNationalId(long nationalId, out DateTime? birthdate) | |
{ | |
//https://lt.wikipedia.org/wiki/Asmens_kodas | |
birthdate = null; | |
if (nationalId < 10000001009 || nationalId > 99912319992) | |
return false; | |
long lastDigit = nationalId % 10; | |
long sum = 0; | |
long tmp = nationalId / 10; | |
int multiplier = 1; | |
for (int i = 9; i >= 0; i--) | |
{ | |
multiplier = (i) % 9 + 1; | |
sum += (tmp % 10) * multiplier; | |
tmp /= 10; | |
} | |
var crc = sum % 11; | |
if (crc == 10) | |
{ | |
tmp = nationalId / 10; | |
sum = 0; | |
for (int i = 9; i >= 0; i--) | |
{ | |
multiplier = (i + 2) % 9 + 1; | |
sum += (tmp % 10) * multiplier; | |
tmp /= 10; | |
} | |
crc = sum % 11; | |
} | |
crc = crc == 10 ? 0 : crc; | |
var valid = crc == lastDigit; | |
if (valid) | |
{ | |
var firstDigit = nationalId / 10000000000; | |
int year = (int)(nationalId / 100000000 % 100); | |
int yearPrefix = 0; | |
int month = (int)(nationalId / 1000000 % 100); | |
int day = (int)(nationalId / 10000 % 100); | |
if (firstDigit == 1 || firstDigit == 2) | |
yearPrefix = 1800; | |
else if (firstDigit == 3 || firstDigit == 4) | |
yearPrefix = 1900; | |
else if (firstDigit == 5 || firstDigit == 6) | |
yearPrefix = 2000; | |
if (month <= 0 || month > 12 || day <= 0 || day > DateTime.DaysInMonth(yearPrefix + year, month)) | |
return (year == 0 && month == 0 && day == 0) && valid; //allow special cases where national id contains no birthdate | |
birthdate = new DateTime(yearPrefix + year, month, day); | |
} | |
return valid; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment