Skip to content

Instantly share code, notes, and snippets.

@danzuep
Last active August 17, 2022 14:43
Show Gist options
  • Save danzuep/80e96f8833eb0989b35d882df9cb1df2 to your computer and use it in GitHub Desktop.
Save danzuep/80e96f8833eb0989b35d882df9cb1df2 to your computer and use it in GitHub Desktop.
O(n) Luhn check
public class Luhn
{
public static bool CheckLuhnDigit(string digits, int last = 1)
{
var checksum = CalculateLuhnDigit(digits, last);
int checkDigit = checksum > -1 ? digits[^last] - '0' : 0;
return checksum == checkDigit;
}
public static int CalculateLuhnDigit(string digits, int lastIndex = 0)
{
int luhnDigit = -1;
lastIndex = Math.Abs(lastIndex);
int minimumLength = 1 + lastIndex;
if (!string.IsNullOrEmpty(digits) && digits.Length > minimumLength)
{
long sum = 0;
for (int i = 0; i < digits.Length - lastIndex; i++)
{
int digit = digits[^(i + minimumLength)] - '0';
if (digit < 0 || digit > 9)
return luhnDigit;
sum += (i % 2 == 0) ? Luhn(digit) : digit;
}
luhnDigit = (int)(10 - (sum % 10)) % 10;
}
return luhnDigit;
int Luhn(int digit) => (digit *= 2) > 9 ? digit - 9 : digit;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment