라이너에서 chatGPT4를 이용한 2주 무료 이용권을 위해 카드 결제 정보를 기입했다.
카드번호를 단 한개 틀렸을 뿐인데, 바로 안다..
카드사가 어딘지도 모르는데!!!
카드 번호의 정확성을 바로 확인할 수 있는 기술은 주로 룬 알고리즘(Luhn Algorithm)이라고 불리는 간단한 체크섬 공식을 이용합니다. 이 알고리즘은 카드 번호가 유효한지 아닌지를 판별하기 위하여 사용되며, 단순한 수학적 절차를 통해 카드 번호가 올바른 구성을 가지고 있는지 실시간 확인이 가능합니다.
카드 번호가 입력되면, 마지막 자리(검증 숫자)를 제외한 각 숫자를 뒤에서부터 한 자리 건너 한 자리씩 2배로 곱합니다.
이렇게 해서 만약 10보다 큰 수가 나오면 그 수의 각 자릿수를 더합니다.
그 후 모든 숫자를 더하고 10으로 나누어 떨어지는지 확인합니다.
10으로 나누어 떨어진다면 카드 번호는 유효하며, 그렇지 않다면 오류 메세지가 표시됩니다.
그리고 나머지 숫자들에 대해서 룬의 체크섬 공식이 적용되어 계산됩니다. 만약 입력하신 카드 번호 한 자리가 틀렸다면 이 체크섬이 맞지 않게 되므로 시스템이 바로 오류를 감지하고 경고문구를 보내게 됩니다.
여기 Luhn 알고리즘의 기본 동작 원리입니다:
신용카드 번호는 보통 16자리 숫자로 구성되어 있습니다. 이 숫자들은 각각 카드의 특정 정보를 나타냅니다.
Luhn 알고리즘은 신용카드 번호의 마지막 숫자를 제외한 모든 숫자를 사용합니다.
오른쪽에서부터 시작하여 홀수 자리에 있는 숫자를 2배합니다. 2번 과정에서 카드 번호의 마지막 숫자를 제외하여 오른쪽에서부터 시작하여 홀수 번째 자리에 있는 숫자를 의미합니다.
이 때, 홀수 자리의 수가 9보다 클 경우, -9를 합니다.
각각의 짝수 자리에 있는 숫자는 그대로 사용합니다.
위에서 얻은 모든 숫자를 더합니다.
마지막으로, 위에서 얻은 총 합이 10의 배수인지 확인합니다. 총 합이 10의 배수라면, 해당 카드 번호는 유효한 번호입니다. 그렇지 않다면, 카드 번호에 오류가 있는 것으로 간주됩니다.
1234 5678 9012 3456
이라는 가상의 카드번호로 계산한 결과이다.
실제 내 카드 번호로 한 결과
신기하넹..
이걸 코드로 구현해보려고 한다.
필요한 전제 조건
1. 숫자에서 숫자제외한 다른거 다 빼주기. 공백, - 같은거
2. 16자리가 맞는지 확인. 아니라면 false
3. 숫자를 배열로.
4. 마지막 배열 pop 해서 잠시 어디 모아두기
5. 15숫자를 reverse 해주기
6. 배열의 n%2=1 이 아닌 자리를 2 해주기
7. 2 해준 홀수자리를 9보다 큰지 작은지 검증해주기
8. 9보다 크면 (어차피 짝수만 나옴) -9를 해줌.
9. 배열의 모든 숫자와 아까 pop 해놓은 수를 더해줌
10. 총합 %10을 했을 때, 그 결과가 0이면 -> 유효한 카드번호 / 아닐경우 -> 유효하지 않은 카드번호
def checkCardNum(num) :
# print(num)
cardNum = [] #카드번호만 담을 것
# 문자열 num 에서 숫자만 추출
for n in num:
if n.isdigit():
# print(n)
cardNum.append(int(n)) #카드번호 배열에 추가
# 16자리가 아닐 경우, false
if len(cardNum) != 16 :
return(False)
# 마지막 숫자는 잠시 빼두기
lastNum = cardNum.pop()
# 숫자배열 거꾸로
cardNum.reverse()
# 배열의 홀수 자리만 2배해주기 -> 따로 계산
singleNum=0
for i in cardNum[::2]:
i*=2
if (i >9):
i-=9
singleNum+=i
doubleNum =0 # 짝수 자리 합산
for i in cardNum[1::2] :
doubleNum+=i
# 다 더해주기
total = singleNum + doubleNum +lastNum
# 10의 배수 확인하기 (삼항연산자)
return True if total%10 ==0 else False
def check_card_number(card_number):
def digits_of(n):
return [int(d) for d in str(n)]
digits = digits_of(card_number)
odd_digits = digits[-1::-2]
even_digits = digits[-2::-2]
checksum = sum(odd_digits)
for d in even_digits:
checksum += sum(digits_of(d*2))
return checksum % 10 == 0
card_number = '1234567890123456' # Replace with the actual card number
if check_card_number(card_number):
print("카드 번호가 유효합니다.")
else:
print("카드 번호가 유효하지 않습니다.")
코드 길이 차이가.. 많이 나네.. ^^ ㅎㅎㅎ
생각보다 룬 알고리즘은 굉장히 쉽고, 구현하기도 편하다.
난 python 으로 구현했지만, 아무래도 프론트 단에서 많이 사용하는 검증 방식이기에, 자바스크립트로 코드 구현하는게 더 유용할듯하다!