Advertisement
jamesdylangoldstein

CS50LuhnChecksum

Jun 12th, 2016
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.77 KB | None | 0 0
  1. //
  2. //  CS50UpdatedLuhn.c
  3. //  CS50UpdatedLuhn
  4. //
  5. //  Created by James Dylan Goldstein on 6/7/16.
  6. //  Rewrote my Luhn's algorithm psetwith functions and shorter/cleaner code
  7. //  Shortening repeated portions with exponents and loops
  8.  
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include "cs50.h"
  12.  
  13. unsigned long long Exponent(unsigned long long base, unsigned long long exponent);
  14. unsigned long long NumDigits(unsigned long long creditcardnum);
  15. unsigned long long DigitAssigner(unsigned long long *digitsarray, unsigned long long creditcardnum);
  16. unsigned long long PrintCardType(unsigned long long *digitsarray, unsigned long long creditcardlength);
  17. unsigned long long DoubleEveryOtherDigit(unsigned long long *digitsarray);
  18. unsigned long long SumDigits(unsigned long long *digitsarray);
  19.  
  20. unsigned long long creditcardlength, creditcardnum, base, exponent;
  21. long long firstsumdigits;
  22.  
  23. int main(int argc, const char * argv[])
  24. {
  25.     printf("Type a credit card number: ");
  26.     creditcardnum = GetLongLong();
  27.     creditcardlength = NumDigits(creditcardnum);
  28.     unsigned long long digitsarray[creditcardlength];
  29.    
  30.     long long timesninemodzero, finalsum;
  31.    
  32.     // Assign each number of the CC to a spot in an array
  33.     DigitAssigner(digitsarray, creditcardnum);
  34.    
  35.     // Identify the type of credit card
  36.     PrintCardType(digitsarray, creditcardlength);
  37.    
  38.     // Starting with the right-most digit, double that digit and do that to every other digit
  39.     // Then if the new doubled number is two digits (example: 7 * 2 = 14)
  40.     // Make the new doubled number one digit by adding both digits together (7 * 2 = 1 + 4)
  41.     // counterc is -1 because a 16 digit card becomes 0-15
  42.     DoubleEveryOtherDigit(digitsarray);
  43.    
  44.     // Sum all the new doubled digits together and all of the remaining original digits
  45.     // Record this sum and leave it for later
  46.     firstsumdigits = SumDigits(digitsarray);
  47.    
  48.     // Create a new variable with the same number as the previous sum
  49.     // Multiply that number by 9 and then find the remainder when divided by 10
  50.     timesninemodzero = firstsumdigits * 9 % 10;
  51.    
  52.     // Take the remainder and added to the saved sum from earlier
  53.     finalsum = firstsumdigits + timesninemodzero;
  54.    
  55.     // If the new final sum divides evenly by 10, it's a valid credit card.
  56.     if (finalsum % 10 == 0)
  57.     {
  58.         printf("This is a valid credit card.");
  59.     }
  60.     else
  61.     {
  62.         printf("This is not a valid credit card.");
  63.     }
  64.    
  65.     return 0;
  66. }
  67.  
  68. // Function for exponentiation, to shorten numbers in code and allow for looping
  69. unsigned long long Exponent(unsigned long long base, unsigned long long exponent)
  70. {
  71.     if (exponent == 0)
  72.     {
  73.         return 1;
  74.     }
  75.     else if (exponent == 1)
  76.     {
  77.         return base;
  78.     }
  79.     else
  80.     {
  81.         unsigned long long result = base;
  82.         for (unsigned long long counter = 2; counter <= exponent; counter++)
  83.         {
  84.             result *= base;
  85.         }
  86.         return result;
  87.     }
  88.    
  89. }
  90.  
  91. // Function that finds the number of digits in a long number
  92. unsigned long long NumDigits(unsigned long long creditcardnum)
  93. {
  94.     unsigned long long digitcounter;
  95.    
  96.     if (creditcardnum <= 0)
  97.         return 0;
  98.     else
  99.     {
  100.         for (digitcounter = 1; digitcounter <= 19; digitcounter++)
  101.         {
  102.             if (creditcardnum < Exponent(10, digitcounter))
  103.                 return digitcounter;
  104.         }
  105.     }
  106.     return 0;
  107. }
  108.  
  109. // Assigns each digit of the credit card number to a place in an array
  110. unsigned long long DigitAssigner(unsigned long long *digitsarray, unsigned long long creditcardnum)
  111. {
  112.     unsigned long long countera;
  113.     unsigned long long creditcardmanip = creditcardnum;
  114.     long long counterb = creditcardlength - 1;
  115.    
  116.     for (countera = 0; countera < creditcardlength; countera++)
  117.     {
  118.         digitsarray[countera] = creditcardmanip/Exponent(10, counterb);
  119.         creditcardmanip = creditcardmanip - (digitsarray[countera]*Exponent(10, counterb));
  120.         counterb--;
  121.     }
  122.     return 0;
  123. }
  124.  
  125. // Function that identifies the type of credit card
  126. unsigned long long PrintCardType(unsigned long long *digitsarray, unsigned long long creditcardlength)
  127. {
  128.     if ((digitsarray[0] == 3 && digitsarray[1] == 4) || (digitsarray[0] == 3 && digitsarray[1] == 7))
  129.     {
  130.         if (creditcardlength == 15)
  131.         {
  132.             printf("This is an American Express card.\n");
  133.         }
  134.         else
  135.         {
  136.             printf("Not a known credit card brand.\n");
  137.         }
  138.     }
  139.     else if (digitsarray[0] == 4)
  140.     {
  141.         if (creditcardlength == 13 || creditcardlength == 16)
  142.         {
  143.             printf("This is a Visa card.\n");
  144.         }
  145.         else
  146.         {
  147.             printf("Not a known credit card brand.\n");
  148.         }
  149.     }
  150.     else if ((digitsarray[0] == 5 && digitsarray[1] == 1) || (digitsarray[1] == 2 || digitsarray[1] == 3) || (digitsarray[1] == 4) || (digitsarray[1] == 5))
  151.     {
  152.         if (creditcardlength == 16)
  153.         {
  154.             printf("This is a MasterCard.\n");
  155.         }
  156.         else
  157.         {
  158.             printf("Not a known credit card brand.\n");
  159.         }
  160.     }
  161.     return 0;
  162. }
  163.  
  164. unsigned long long DoubleEveryOtherDigit(unsigned long long *digitsarray)
  165. {
  166.     long long counterc = creditcardlength - 1;
  167.    
  168.     while (counterc >= 0)
  169.     {
  170.         digitsarray[counterc] *= 2;
  171.         if(digitsarray[counterc] > 9)
  172.         {
  173.             digitsarray[counterc] = digitsarray[counterc] % 10 + 1;
  174.         }
  175.         counterc -= 2;
  176.     }
  177.    
  178.     return 0;
  179. }
  180.  
  181. unsigned long long SumDigits(unsigned long long *digitsarray)
  182. {
  183.     for (int counterd = 0; counterd < creditcardlength; counterd++)
  184.     {
  185.         firstsumdigits += digitsarray[counterd];
  186.     }
  187.     return firstsumdigits;
  188. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement