3/05/2010

Credit Card Number Validation

Credit Card Number Validation
카드 번호로 카드 회사 구분하기

주어진 Credit Card 번호로 Card Issuer 결정하기.
Credit Card Number로 Card 발행업체를 알아보자.

위키의 내용을 참고해 만들었다.
위키를 보면 대부분의 major 카드 회사들은 유효한 카드 번호인지 확인하기 위해 Luhn algorithm을 쓴다.

아래소스는 Visa, Master, Amex, DinersClub, Discover, JCB, CUP 카드만을 체크할 수 있다.

//Enum
public enum CardIssuer { None, VISA, MASTER, AMEX, DINERSCLUB, DISCOVER, JCB, CUP }

//Card Issuer 결정하기
public static CardIssuer GetCardIssuer(string cardNum)
{
    if (IsValidVisaCard(cardNum))
        return CardIssuer.VISA;

    if (IsValidMasterCard(cardNum))
        return CardIssuer.MASTER;

    if (IsValidDiscoverCard(cardNum))
        return CardIssuer.DISCOVER;

    if (IsValidAmexCard(cardNum))
        return CardIssuer.AMEX;

    if (IsValidDinersClubCard(cardNum))
        return CardIssuer.DINERSCLUB;

    if (IsValidJcbCard(cardNum))
        return CardIssuer.JCB;

    if (IsValidCupCard(cardNum))
        return CardIssuer.CUP;

    return CardIssuer.None;
}

public static bool IsValidVisaCard(string cardNum)
{
    int cardNumLen = cardNum.Length;
    int cardPrefix = Int32.Parse(cardNum.Substring(0, 1));

    if (cardPrefix != 4)
        return false;

    if (cardNumLen != 13 && cardNumLen != 16)
        return false;

    if (!IsValidCardNumber(cardNum))
        return false;
    
    return true;
}

public static bool IsValidMasterCard(string cardNum)
{
    int cardNumLen = cardNum.Length;
    int cardPrefix = Int32.Parse(cardNum.Substring(0, 2));

    if (cardPrefix < 51 || cardPrefix > 55)
        return false;

    if (cardNumLen != 16)
        return false;

    if (!IsValidCardNumber(cardNum))
        return false;

    return true;
}

public static bool IsValidAmexCard(string cardNum)
{
    int cardNumLen = cardNum.Length;
    int cardPrefix = Int32.Parse(cardNum.Substring(0, 2));

    if (cardPrefix != 34 && cardPrefix != 37)
        return false;

    if (cardNumLen != 15)
        return false;

    if (!IsValidCardNumber(cardNum))
        return false;

    return true;
}

public static bool IsValidDinersClubCard(string cardNum)
{
    int cardNumLen = cardNum.Length;
    int cardPrefix = Int32.Parse(cardNum.Substring(0, 2));

    if (cardPrefix != 36)
        return false;

    if (cardNumLen != 14)
        return false;

    if (!IsValidCardNumber(cardNum))
        return false;

    return true;
}

public static bool IsValidDiscoverCard(string cardNum)
{
    int cardNumLen = cardNum.Length;
    int cardPrefix = Int32.Parse(cardNum.Substring(0, 7));

    if (cardPrefix < 6011000 || cardPrefix > 6011090)
        if(cardPrefix < 6011200 || cardPrefix > 6011490)
            if (cardPrefix < 6011740 || cardPrefix > 6011749)
                if (cardPrefix < 6011770 || cardPrefix > 6011790)
                    if (cardPrefix < 6011860 || cardPrefix > 6011990)
                        if (cardPrefix < 6500000 || cardPrefix > 6509990)
                            return false;

    if (cardNumLen != 14)
        return false;

    if (!IsValidCardNumber(cardNum))
        return false;

    return true;
}

//Global Payments processes JCB as a Private Label card type. Currently, JCB is supported in Private Label 0 or Private Label 1. This value is defined by the merchant's bank.
public static bool IsValidJcbCard(string cardNum)
{
    int cardNumLen = cardNum.Length;
    int cardPrefix = Int32.Parse(cardNum.Substring(0, 6));

    if (cardPrefix < 352800 && cardPrefix > 358999)
        return false;

    if (cardNumLen != 14)
        return false;

    if (!IsValidCardNumber(cardNum))
        return false;

    return true;
}

//CUP(china Union Pay)transactions are processed through an agreement with the Discover Network through Global Payments.
public static bool IsValidCupCard(string cardNum)
{
    int cardNumLen = cardNum.Length;
    int cardPrefix = Int32.Parse(cardNum.Substring(0, 8));

    if (cardPrefix < 62212600 || cardPrefix > 62292599)
        return false;

    if (cardNumLen != 14)
        return false;

    if (!IsValidCardNumber(cardNum))
        return false;

    return true;
}

//Luhn algorithm http://en.wikipedia.org/wiki/Luhn_algorithm
public static bool IsValidCardNumber(string cardNumber)
{
   const string allowed = "0123456789";
   int i;

   StringBuilder cleanNumber = new StringBuilder();
   for (i = 0; i < cardNumber.Length; i++)
   {
      if (allowed.IndexOf(cardNumber.Substring(i, 1)) >= 0)
         cleanNumber.Append(cardNumber.Substring(i, 1));
   }
   if (cleanNumber.Length < 13 || cleanNumber.Length > 16)
      return false;

   for (i = cleanNumber.Length + 1; i <= 16; i++)
      cleanNumber.Insert(0, "0");

   int multiplier, digit, sum, total = 0;
   string number = cleanNumber.ToString();

   for (i = 1; i <= 16; i++)
   {
      multiplier = 1 + (i % 2);
      digit = int.Parse(number.Substring(i - 1, 1));
      sum = digit * multiplier;
      if (sum > 9)
         sum -= 9;
      total += sum;
   }
   return (total % 10 == 0);
}

참고문서:
 Credit Card Number 위키 - http://en.wikipedia.org/wiki/Credit_card_number
 Luhn algorithm - http://en.wikipedia.org/wiki/Luhn_algorithm
 알고리즘 소스 - http://www.codeguru.com/csharp/.net/net_security/authentication/article.php/c12283/

댓글 없음:

댓글 쓰기