Thursday, 21 June 2012

Credit / Debit Card numbers generator and Validator

I just wanted to generate few sample valid credit/debit card numbers for testing purpose in banking domain few days ago. So, thought of writing some logic to generate the valid credit/debit card numbers and/or validate the given credit/debit card numbers.


Here is the logic of how the 16 digit credit/debit card numbers are generated

1. First 6 digits are the Bank/Issuer Identification number (typically known as BIN or IIN)
2. Next 9 digits are any random digits
3. The last digit is a checksum digit

The last digit is a valid checksum digit, only if below condition is satisfied

1. double each alternative odd positioned digits e.g. 1st, 3rd, 5th,....,15th
2. if the doubled number is of 2 digits then sum up the digits of that number to get a single digit number
3. Then sum up all the 16 digits from the card number in newly generated sequence of digits
4. Check if the sum is completely divisible by 10 - if yes, the cardNumber is valid one

This check is also know as LUHN check.

This logic is automated in below attached program. This simple program has ability to

1. Generate any number of valid credit/debit card numbers if the Bank Identification number is provided. This is typically required to generate the test data for bulk testing in banking/credit/debit card domains

2. Generate any number of valid credit/debit card numbers even if you don't provide any BIN. (The westpac Mastercard BIN is hardcoded in the program :) )

3. Validate the given credit card number

You may quickly test this program by entering your debit/credit card number.

  1.  /** This program is to generate the sample valid credit and debit card numbers provided the BIN (Bank Identification Number).
  2.  * It also can check whether the given credit card number is valid one by applying the LUHN check.
  3.  * The program should not strictly be used to do any fraud of the credit cards, this has its genuine purpose of testing only.
  4.  *
  5.  * @description
  6.  * Any 16 digit credit/debit card number is made up of
  7.  * 1. first 6 digits BIN
  8.  * 2. 9 digits random account number
  9.  * 3. last 1 digit checksum
  10.  * @author: Balaji Londhe
  11.  * @contact: sbalajipune@gmail.com
  12.  */
  13.  
  14. import java.io.*;
  15.  
  16. public class CreditCardNumberGeneratorAndValidator {
  17.         public static void main(String args[]) throws Exception {
  18.                 BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  19.                 String ans = "";
  20.                 do {
  21.                         System.out.println("\nMenu: " +
  22.                                                         "\n\n1. Generate the card numbers by BIN (Bank / Issuer Identification Number)" +
  23.                                                         "\n2. I don't have BIN (Bank / Issuer Identification Number). Please give me some sample card numbers " +
  24.                                                         "\n3. Check if given card number is valid " +
  25.                                                         "\n4. Exit\n");
  26.                        
  27.                         System.out.print("Please enter your choice: ");
  28.                         int choice = Integer.parseInt(br.readLine().trim());
  29.                         switch (choice)
  30.                         {
  31.                                 case 1:
  32.                                         System.out.print("Enter the 6 digits BIN: ");
  33.                                         String bin = br.readLine().trim();
  34.                                         System.out.print("How many cards you want to generate?: ");
  35.                                         int noOfCardsToBeGenerated = Integer.parseInt(br.readLine().trim());
  36.                                         String[] cardNumbers = generateCardNumberByBIN(bin, noOfCardsToBeGenerated);
  37.                                         if (cardNumbers != null)
  38.                                         {
  39.                                                 System.out.println("\nThe card numbers for BIN " + bin + " are as below:\n");
  40.                                                 for (int i = 0; i < cardNumbers.length; i++)
  41.                                                 {
  42.                                                         System.out.println(i + 1 + ". " + cardNumbers[i]);
  43.                                                 }
  44.                                                 System.out.println();
  45.                                         }
  46.                                         break;
  47.                                 case 2:
  48.                                         String bin1 = "516300"; // BIN of Westpac Mastercard
  49.                                         System.out.print("How many card numbers you want to generate?: ");
  50.                                         int noOfCardsToBeGenerated1 = Integer.parseInt(br.readLine().trim());
  51.                                         String[] cardNumbers1 = generateCardNumberByBIN(bin1, noOfCardsToBeGenerated1);
  52.                                         if (cardNumbers1 != null)
  53.                                         {
  54.                                                 System.out.println("\nThe card numbers for BIN " + bin1 + " are as below:\n");
  55.                                                 for (int i = 0; i < cardNumbers1.length; i++)
  56.                                                 {
  57.                                                         System.out.println(i + 1 + ". " + cardNumbers1[i]);
  58.                                                 }
  59.                                                 System.out.println();
  60.                                         }
  61.                                         break;
  62.                                 case 3:
  63.                                         System.out.print("Please enter the 16 digit card number to validate : ");
  64.                                         String cardNumber = br.readLine().trim();
  65.                                         boolean flag = isCardNumberValid(cardNumber);
  66.                                         if (flag)
  67.                                         {
  68.                                                 System.out.println("\nThe card number you have enetered is VALID");
  69.                                         }
  70.                                         else
  71.                                         {
  72.                                                 System.out.println("\nThe card number you have enetered is NOT valid");
  73.                                         }
  74.                                         break;
  75.                                 case 4:
  76.                                         System.exit(0);
  77.                                 default:
  78.                                         System.out.println("Please enter the correct choice...");
  79.                         }
  80.                         System.out.print("Do you want to continue[y/n]? ");
  81.                         ans = br.readLine();
  82.                 } while ("y".equalsIgnoreCase(ans));
  83.         }
  84.  
  85.         private static String[] generateCardNumberByBIN(String bin, int noOfCardsToBeGenerated) throws Exception
  86.         {
  87.                 // check if the BIN given is of 6 digits in length
  88.                 if (bin != null && bin.trim().length() == 6)
  89.                 {
  90.                         String cardNumbers[] = new String[noOfCardsToBeGenerated];
  91.                         // Append the 9 digit account number to BIN number randomly
  92.                         for (int j = 0; j < noOfCardsToBeGenerated; j++)
  93.                         {
  94.                                 StringBuffer cardNumber = new StringBuffer(bin);
  95.                                 for (int i = 1; i <= 9; i++)
  96.                                 {
  97.                                         cardNumber.append((int) (Math.random() * 10));
  98.                                 }
  99.                                 boolean isCardNumberInArray = false;
  100.                                 do
  101.                                 {
  102.                                         // Try the checksum digit from 0 to 9 to pass through LUHN
  103.                                         // check
  104.                                         for (int i = 0; i <= 9; i++)
  105.                                         {
  106.                                                 StringBuffer temp = new StringBuffer(cardNumber.toString());
  107.                                                 temp.append(i);
  108.                                                 boolean isValidCardNumber = isCardNumberValid(temp.toString());
  109.                                                 if (isValidCardNumber)
  110.                                                 {
  111.                                                         // check if the card number is in array already - to
  112.                                                         // avoid the duplicate one
  113.                                                         for (int k = 0; k < cardNumbers.length; k++)
  114.                                                         {
  115.                                                                 if (temp.toString().equals(cardNumbers[k]))
  116.                                                                 {
  117.                                                                         isCardNumberInArray = true;
  118.                                                                         break;
  119.                                                                 }
  120.                                                         }
  121.                                                         if (!isCardNumberInArray)
  122.                                                         {
  123.                                                                 isCardNumberInArray = false;
  124.                                                                 cardNumbers[j] = temp.toString();
  125.                                                                 break;
  126.                                                         }
  127.                                                 }
  128.                                         }
  129.                                 } while (isCardNumberInArray);
  130.                         }
  131.                         return cardNumbers;
  132.                 }
  133.                 else
  134.                 {
  135.                         System.out.println("The BIN you have entered in not 6 digits...\n");
  136.                         return null;
  137.                 }
  138.         }
  139.        
  140.         private static boolean isCardNumberValid(String cardNumber) throws Exception
  141.         {
  142.                 boolean flag = false;
  143.                 if (cardNumber != null && cardNumber.length() == 16)
  144.                 {
  145.                         // convert cardNumber to an integer array
  146.                         int[] array = new int[cardNumber.length()];
  147.                         for (int i = 0; i < cardNumber.length(); i++)
  148.                         {
  149.                                 array[i] = cardNumber.charAt(i) - 48;
  150.                         }
  151.                        
  152.                         /*
  153.                          * Apply the LUHN check
  154.                          *
  155.                          * 1. double each alternative odd positioned digits e.g. 1st, 3rd,
  156.                          * 5th,....,15th
  157.                          *
  158.                          * 2. if the doubled number is of 2 digits then sum up the digits of
  159.                          * that number to get a single digit number
  160.                          *
  161.                          * 3. Sum up all the 16 digits in new generated sequence of digits
  162.                          *
  163.                          * 4. Check if the sum is completely divisible by 10 - if yes, the
  164.                          * cardNumber is valid one
  165.                          */
  166.  
  167.                         int totalSum = 0;
  168.                         for (int i = 1; i <= array.length; i++)
  169.                         {
  170.                                 int doubledNumber = array[i - 1];
  171.                                 if (i % 2 == 1) // odd positioned digits
  172.                                 {
  173.                                         doubledNumber = array[i - 1] * 2;
  174.                                         String temp = String.valueOf(doubledNumber);
  175.                                         if (temp.length() == 2)
  176.                                         {
  177.                                                 int sum = (temp.charAt(0) - 48) + (temp.charAt(1) - 48);
  178.                                                 doubledNumber = sum;
  179.                                         }
  180.                                 }
  181.                                 totalSum += doubledNumber;
  182.                         }
  183.                         if (totalSum % 10 == 0)
  184.                         {
  185.                                 flag = true;
  186.                         }
  187.                 }
  188.                 else
  189.                 {
  190.                         System.out.println("The card number needs to be of 16 digit...\n");
  191.                 }
  192.                 return flag;
  193.         }
  194. }
  195.  

2 comments: