Skip to content

Instantly share code, notes, and snippets.

@Dissimilis
Last active November 30, 2021 09:45
Show Gist options
  • Save Dissimilis/22ee7b33bdc79e24a0b8e5fbf9c2fc0a to your computer and use it in GitHub Desktop.
Save Dissimilis/22ee7b33bdc79e24a0b8e5fbf9c2fc0a to your computer and use it in GitHub Desktop.
Lithuanian national id validator in C# .NET. Lietuviško asmens kodo validavimas.
//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