Credit cards use the Luhn Check Digit Algorithm. The main purpose of the Luhn Check Digit Algorithm is to catch data entry errors, but it does double duty here as a weak security tool.

The Luhn Check Digit Algorithm

For a card with an even number of digits, double every odd numbered digit (1st digit, 3rd digit, 5th digit, etc…) and subtract 9 if the product is greater than 9. Add up all the even digits (2nd digit, 4th digit, 6th digit, etc…) as well as the doubled-odd digits, and the result must be a multiple of 10 or it’s not a valid card. If the card has an odd number of digits, perform the same addition doubling the even numbered digits instead.

The Luhn Check Digit Algorithm in C

This program, presented in C source code form, will perform this math for you. Feed it all but the last digit of your credit card number, and it will give you the last digit. If it gives you a last digit different
from the one you have, you have an invalid credit card number.

#include <stdio.h>

/*
 * Return last digit of a bank card (e.g. credit card)
 * Receives all the digits, but the last one as input
 * By Diomidis Spinellis <dds@doc.ic.ac.uk>
 */
int bank (u)char *u;
     {
     register i, s = 0;
     int l, t;

     l = strlen(u);
     for(i = 0; i < l ; i++)
     {
        t = (u[l - i - 1] - '0') * (1 + ((i + 1) % 2));
        s += t < 10 ? t : t - 9;
     }
     return 10 - s % 10;
     }

void main (argc, argv)

int argc;
char **argv;
     {
     while (--argc)
        printf ("%dn", bank (*++argv));
     }

The Luhn Check Digit Algorithm in Java

//---------------------------------------------------------
// Checks for valid credit card number using Luhn algorithm
//---------------------------------------------------------

public abstract class LuhnCheck {

  //--------------------------------
  // Filter out non-digit characters
  //--------------------------------

  private static String getDigitsOnly (String s) {
    StringBuffer digitsOnly = new StringBuffer ();
    char c;
    for (int i = 0; i < s.length (); i++) {
      c = s.charAt (i);
      if (Character.isDigit (c)) {
        digitsOnly.append (c);
      }
    }
    return digitsOnly.toString ();
  }

  //-------------------
  // Perform Luhn check
  //-------------------

  public static boolean isValid (String cardNumber) {
    String digitsOnly = getDigitsOnly (cardNumber);
    int sum = 0;
    int digit = 0;
    int addend = 0;
    boolean timesTwo = false;

    for (int i = digitsOnly.length () - 1; i >= 0; i--) {
      digit = Integer.parseInt (digitsOnly.substring (i, i + 1));
      if (timesTwo) {
        addend = digit * 2;
        if (addend > 9) {
          addend -= 9;
        }
      }
      else {
        addend = digit;
      }
      sum += addend;
      timesTwo = !timesTwo;
    }

    int modulus = sum % 10;
    return modulus == 0;

  }

  //-----
  // Test
  //-----

  public static void main (String[] args) {
    String cardNumber = "4408 0412 3456 7890";
    boolean valid = LuhnCheck.isValid (cardNumber);
    System.out.println (cardNumber + ": " + valid);
    cardNumber = "4408 0412 3456 7893";
    valid = LuhnCheck.isValid (cardNumber);
    System.out.println (cardNumber + ": " + valid);
    cardNumber = "4417 1234 5678 9112";
    valid = LuhnCheck.isValid (cardNumber);
    System.out.println (cardNumber + ": " + valid);
    cardNumber = "4417 1234 5678 9113";
    valid = LuhnCheck.isValid (cardNumber);
    System.out.println (cardNumber + ": " + valid);
  }

}