cbits/pii.c
bool warden_check_creditcard(const char *buf, size_t n) {
	char c;
	size_t i;
	int luhn_sum = 0;
	int num_digits = 0;
	bool doubling_digit = FALSE;

	/* CC numbers are of varying length, but no major vendor is
	 * less than 12 bytes (Maestro). The longest is VISA (19),
	 * and we need some room for filler characters, but due to the
	 * potential for unpredictable amounts of padding we don't
	 * check the upper bound here. */
	if (n < 12) {
		return FALSE;
	}

	/* Walk backwards through the field accumulating a Luhn sum
	 * and exiting early if we see impossible things. */
	for (i = n; i > 0; i--) {
		c = buf[i-1];
		/* If it's a digit, add its numeric value to the Luhn
		 * sum. */
		if (is_digit(c)) {
			int x = c - '0';

			num_digits++;

			/* We double every second digit from the right-hand-side
			 * (starting with the penultimate digit). */
			if (doubling_digit) {
				x *= 2;
				if (x > 9) {
					x -= 9;
				}
			}
			luhn_sum += x;
			doubling_digit = ~doubling_digit;
		}
		/* Letters and random punctuation don't belong here,
		 * but we expect hyphens or spaces. */
		else if (!is_number_filler(c)) {
			return FALSE;
		}
	}

	/* Check digit must be correct and we must have seen at least
	 * twelve digits (to avoid cases like "0-----------"
	 * matching). */
	return (luhn_sum % 10 == 0) && (num_digits >= 12);
}
/* Use the Luhn algorithm to check for potential credit card numbers,
 * after performing some sanity checks on the length.
 *
 * https://en.wikipedia.org/wiki/Luhn_algorithm */
Use the Luhn algorithm to check for potential credit card numbers,
after performing some sanity checks on the length.


Use the Luhn algorithm to check for potential credit card numbers after performing some sanity checks on the length .
bool warden_check_creditcard(const char *buf, size_t n) {
	char c;
	size_t i;
	int luhn_sum = 0;
	int num_digits = 0;
	bool doubling_digit = FALSE;
	if (n < 12) {
		return FALSE;
	}
	for (i = n; i > 0; i--) {
		c = buf[i-1];
		if (is_digit(c)) {
			int x = c - '0';
			num_digits++;
			if (doubling_digit) {
				x *= 2;
				if (x > 9) {
					x -= 9;
				}
			}
			luhn_sum += x;
			doubling_digit = ~doubling_digit;
		}
		else if (!is_number_filler(c)) {
			return FALSE;
		}
	}
	return (luhn_sum % 10 == 0) && (num_digits >= 12);
}
bool warden_check_creditcard ( const char * buf , size_t n ) { char c ; size_t i ; int luhn_sum = 0 ; int num_digits = 0 ; bool doubling_digit = FALSE ; if ( n < 12 ) { return FALSE ; } for ( i = n ; i > 0 ; i -- ) { c = buf [ i - 1 ] ; if ( is_digit ( c ) ) { int x = c - ' ' ; num_digits ++ ; if ( doubling_digit ) { x *= 2 ; if ( x > 9 ) { x -= 9 ; } } luhn_sum += x ; doubling_digit = ~ doubling_digit ; } else if ( ! is_number_filler ( c ) ) { return FALSE ; } } return ( luhn_sum % 10 == 0 ) && ( num_digits >= 12 ) ; }
Use the Luhn algorithm to check for potential credit card numbers,
 after performing some sanity checks on the length.
Use the Luhn algorithm to check for potential credit card numbers after performing some sanity checks on the length .
/* CC numbers are of varying length, but no major vendor is
	 * less than 12 bytes (Maestro). The longest is VISA (19),
	 * and we need some room for filler characters, but due to the
	 * potential for unpredictable amounts of padding we don't
	 * check the upper bound here. */ /* Walk backwards through the field accumulating a Luhn sum
	 * and exiting early if we see impossible things. */ /* If it's a digit, add its numeric value to the Luhn
		 * sum. */ /* We double every second digit from the right-hand-side
			 * (starting with the penultimate digit). */ /* Letters and random punctuation don't belong here,
		 * but we expect hyphens or spaces. */ /* Check digit must be correct and we must have seen at least
	 * twelve digits (to avoid cases like "0-----------"
	 * matching). */