OpenVMS Source Code Demos

credit_card_number_test

//==============================================================================
// title     : credit_card_number_test_100.c
// author    : Neil Rieck	( https://neilrieck.net		)
//				( eml: [email protected]	)
// created   : 2017-09-20
// references: New Scientist (23 Aug 2017) "Authority figures: The numbers that rule them all"
//             Wikipedia: https://en.wikipedia.org/wiki/Luhn_algorithm
//             Wikipedia: https://en.wikipedia.org/wiki/International_Mobile_Equipment_Identity
//==============================================================================
#include <stdio.h>			// printf
#include <stdlib.h>			// atoi
#include <string.h>			// strlen
#include <stdbool.h>			// bool
//------------------------------------------------------------------------------
//	checkLuhn (algorithm by Hans Peter Luhn)
//
//	notes:	the following example assumes account number is 7992739871 with check digit of 3
//	steps:	1) scan string from right-to-left
//			1a) copy down the even position values as-is
//			1b) double the numeric value of the odd positions
//			    if the just-doubled digit is less <= 9
//				then copy down the doubled digit
//				otherwise copy down the sum of the doubled digits (eg. for 16, use 1+6=7)
//		2) sum all the digits in row #4 (70 in the example below)
//		3) if the sum is evenly divisible by 10 then the number is probably correct
//
//	Position (Odd/Even)	10	09	08	07	06	05	04	03	02	01	00
//	===================	==	==	==	==	==	==	==	==	==	== 	==
//	Account number    :	7	9	9	2	7	3	9	8	7	1   |	3
//	Double every odd  :		18		4		6		16		2   |
//	Scratch           :		1+8=9						1+6=7		    |
//	Sum digits        :	7	9	9	4	7	6	9	7	7	2   |   3
//------------------------------------------------------------------------------
//	Notes about generating a check digit from an account number:
//	1) grab your all numeric account number then tack on a zero
//	2) run the result through the algorithm
//	3) multiply the final sum by 9
//	4) the units digit of the result will be the check digit
//------------------------------------------------------------------------------
bool checkLuhn(const char *pPurported)
{
    int nSum       = 0;
    int nDigits    = strlen(pPurported);
    int nParity    = (nDigits-1) % 2;
    char cDigit[2] = "\0";
    //
    for (int i = nDigits; i > 0 ; i--)
    {
      cDigit[0]  = pPurported[i-1];
      int nDigit = atoi(cDigit);

      if (nParity == i % 2)
        nDigit = nDigit * 2;

      nSum += nDigit/10;
      nSum += nDigit%10;
    }
    return (0 == nSum % 10);
}
//
//	the grand Grand Poobah
//
void main() {
	char		yada[32];
	long long	test;		// 64-bit integer
	bool		pass;
	//
	printf("enter one of the following:\n");
	printf("  Credit Card Number\n");
	printf("  Canadian social insurance number\n");
	printf("  Greek social insurance number\n");
	printf("  Israeli identification number\n");
	printf("  79927398713\n");
	printf("data? ");
	gets(yada);
	test = atoll(yada);	// is the string all numeric?
//	printf("value of yada: %lld\n",test);
	if (test<=0){
	    pass = FALSE;	// nope
	    printf("-e-error: the string is not all numeric\n");
	}else{
	    pass = checkLuhn(yada);
	}
	if (pass==TRUE){
		printf("probably valid: true\n");
	}else{
		printf("valid: false\n");
	}
}

Back to Home
Neil Rieck
Waterloo, Ontario, Canada.