본문 바로가기

디지털포렌식(Digital forensic)/숫자

[파일]신용 카드 유효성 검사, Luhn 코드

반응형

 

아메리칸 익스프레스(American Express) 카드를 예로 든다.

1. 양각처리
     ㄴ American Express 카드 계좌 번호는 양각 처리되어 있다.
     ㄴ 양각(튀어나오게 만듦)은 음각(파내는 방식)보다 복사하기가 더 어렵다.

2. 고유번호
     ㄴ아메리칸 익스프레스 카드는 "3"으로 시작하고 "7" 또는 "4"가 뒤에 온다.
     ㄴ Visa 카드 번호는 "4"로 시작하고 13자리 또는 16자리 숫자로 구성된다.
     ㄴ MasterCard는 "5"로 시작하고 16자리 숫자로 구성된다.
     ㄴ Discover는 "6"으로 시작하고 16자리로 이루어져 있다.
     ㄴ 숫자 그룹은 4자리씩 4개의 그룹으로 구분되어 있다.
     ㄴ 아메리칸 익스프레스 카드 번호는 카드 발급자 식별번호(IIN)을 ANSI 표준에 따른다.
         ㄴ INN은 Issuer Identification Number 또는 BIN(Bank Identification Number)라고 한다.
         ㄴ IIN에 따라 AE 카드는 375987 이다

3. 고유번호 검증
    ㄴ 대부분의 신용 카드 번호는 Luhn 알고리즘(Luhn 공식 또는 모듈러스 10, mod 10)을 사용한다.

 

고유번호 검증 알고리즘
  1. 가장 오른쪽 숫자를 "검사 숫자"라고 한다.
    여기부터 시작하여 왼쪽으로 이동하면 두번째 숫자 옵셋들은 숫자의 값이 두 배가 된다. 
    각 배수가 연산의 결과 합계가 9보다 큰 경우(예: 5 x 2 = 10)에는
    합계의 숫자를 더한다(예: 10:1 + 0 = 1 또는 18:1 + 8 = 9).
  2. 두 배가 되지 않은 홀수를 포함하여 결과 숫자를 모두 더한다.
  3. 결과 합계가 0으로 끝나면 Luhn 공식에 따라 카드 번호가 유효하지만, 그렇지 않으면 유효하지 않다.
  4. 예) 3712 3883 9571 772

출처: 디지털 프로파일러 이정욱 교수

   5. 카드번호를 더블 디지트화 시키고 합계를 낸 값이 70,
      ㄴ 뒷 자리가 0으로 끝나면 Luhn 알고리즘 테스트를 통과한다.

 

using System;

public class LuhnAlgorithm
{
    public static bool ValidateCreditCardNumber(string cardNumber)
    {
        // 오른쪽 끝자리부터 코드 처리하므로 카드 번호를 뒤집는다.
        char[] cardNumberArray = cardNumber.ToCharArray();
        Array.Reverse(cardNumberArray);
        string reversedCardNumber = new string(cardNumberArray);

        int sum = 0;
        bool doubleDigit = false;

        // 뒤집힌 카드 번호의 각 자리 숫자를 반복하여 처리합니다.
        foreach (char digit in reversedCardNumber)
        {
            if (Char.IsDigit(digit))
            {
                int num = (int)Char.GetNumericValue(digit);

                // 짝수 위치의 숫자를 두 배로 곱합니다.
                if (doubleDigit)
                {
                    num *= 2;
                    if (num > 9)
                    {
                        num -= 9;
                    }
                }

                sum += num;
                doubleDigit = !doubleDigit;
            }
            else
            {
                // 숫자가 아닌 문자가 포함되어 있으면 유효하지 않다.
                return false;
            }
        }

        // 총 합이 10의 배수인지 확인하여 유효성을 결정합니다.
        return sum % 10 == 0;
    }

    public static void Main(string[] args)
    {
        string cardNumber = "371238839571772"; // 카드 번호

        if (ValidateCreditCardNumber(cardNumber))
        {
            Console.WriteLine("유효한 카드");
        }
        else
        {
            Console.WriteLine("유효하지 않은 카드 번호");
        }
    }
}

위 코드에 예제로 사용한 카드 번호 371238839571772를 입력하면 '유효하다'라는 결과가 나오지만
끝의 2를 1로 바꾸면 합계가 69가 되서 끝자리가 9이므로 유효하지 않다는 결과가 나온다.


카드 번호를 잘못 입력하면 '유효하지 않은 번호입니다'라는 메시지의 원리는 이거다.

 

ConsoleApp1.zip
0.03MB

 

728x90