3/31/2010

.config 파일을 언제 어디서 불러와야 할까?

말 그대로 config 파일을 언제 어디에서 불러와야 할까!?

  1. 어디에서!?
    처음프로젝트를 만들때에는 이파일 저파일에서 config에 저장되어있는 key값을 불러들였다. 이렇게 하면 나중에 유지보수시에 여러 불편함이 생기는걸 알게 되었다.하나의 key이름을 변경하면 config 파일을 불러온 모든 곳에서 수정을 해주는 등의 수고가 생기는 것이다.

    해서 별도의 Settings Class를 제작해 이곳에서 config 파일의 모든 key값을 불러들이고 다른 곳에서 Settings Class의 Properties를 통해서 접근하는것이 가독성과 유지보수면에서 유용할 것이라는 생각이 들었다.



  2. 언제!?
    MVP 패턴을 이용해 프로젝트를 진행하고 있었는데 이때에는 Presenter의 생성자에서 Settings Class 인스턴스를 생성해 설정값을 읽어들이고 그 값들을 바로 Business Logic에 활용하는 것이 이로울 것이라는 생각을 했다.

    Set할때는 Settings UI에서 Settings Class 인스턴스를 생성해 바꿔주거나 직접 config 파일을 열어 변경해주면 되겠다!!


Config file의 수정및 읽어들이는 방법은 App.config 읽고 쓰기 포스팅을 참조하자.


참고:이 지식들을 신뢰하지 말것..내 자신이 의심스러움 :(

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/