https://ko.wikipedia.org/wiki/%EC%B9%B4%EB%93%9C_%EB%B2%88%ED%98%B8%EC%9D%98_%EA%B5%AC%EC%84%B1
→ 여기서 카드 번호의 구성 확인 가능
1. 주 산업 식별번호 (MII, Master Industry Identifier)
- 카드번호 첫 번째 자리
숫자 | 산업 |
0 | ISO/TC 68 및 기타 |
1 | 항공/교통 |
2 | 멤버십 |
3 | 여행/엔터 (JCB, 아멕스, 다이너스 클럽 등) |
4 | VISA |
5 | Mastercard/마에스트로 |
6 | 디스커버, 은련 |
7 | 석유 등 기타 |
8 | 헬스케어/통신 |
9 | 해외결제 불가 |
2. 발급자 식별번호 (IIN/BIN, Issuer Identification Number)
- 카드번호 앞 6자리
- 카드사와 카드 종류 구분 가능
카드사 | IIN 범위 | 전체 자릿수 |
아멕스 | 34, 37 | 15 |
VISA | 4 | 16 |
마에스트로, 시러스 | 50, 56~59 | 16 |
마스터카드 | 51~55(2221~2720 2017년부터~) | 16 |
은련 | 622126~622925, 624~626, 6282~6288 | 16 |
다이너스 클럽 | 300~305, 3095, 36, 38, 39 | 14 |
디스커버 | 60110, 60112~60114, 601174~601179, 601186~601199, 644~649, 65(60,61,64,65) | 16 |
JCB | 3528, 3589 | 16 |
3. 룬 알고리즘(Luhn Algorithm)으로 카드번호 유효성 검사
def luhn_check(card_number):
card_number = [int(x) for x in str(card_number)]
check_sum = 0
# 역순으로 순회하며 홀짝 구분
for i, num in enumerate(reversed(card_number)):
if i % 2 == 1:
num *= 2
if num > 9:
num -= 9
check_sum += num
return check_sum % 10 == 0
# 예시
print(luhn_check("4539578763621486")) # True
print(luhn_check("4539578763621485")) # False
룬 알고리즘 (Luhn Algorithm) 이란?
→ 신용카드, 주민번호, IMEI 같은 숫자 코드가 유효한지 검증하는 방법
1954년에 IBM의 한 과학자 Hans Peter Luhn이 고안
쉽게 말하면, 카드번호가 실수로 틀린 번호인지 빠르게 확인하는 간단한 수학 공식
작동 방법
카드번호가 4539 5787 6362 1486라면
오른쪽부터 하나씩 숫자를 순서대로:
- 짝수 번째 자리의 숫자는 그대로 두고
- 홀수 번째 자리의 숫자는 2배를 곱하기
- 만약 2배한 값이 9보다 크면 9를 뺌 (또는 각 자리수 합)
- 이렇게 변환된 값들을 전부 더해서
- 그 합이 10으로 나누어떨어지면 유효한 번호
예시
카드번호: 4539 5787 6362 1486
오른쪽부터
자리 | 숫자 | 위치 | 처리 |
6 | 6 | 홀수 | 6×2=12 → 12-9=3 |
8 | 8 | 짝수 | 8 |
4 | 4 | 홀수 | 4×2=8 |
1 | 1 | 짝수 | 1 |
2 | 2 | 홀수 | 2×2=4 |
6 | 6 | 짝수 | 6 |
3 | 3 | 홀수 | 3×2=6 |
6 | 6 | 짝수 | 6 |
7 | 7 | 홀수 | 7×2=14 → 14-9=5 |
8 | 8 | 짝수 | 8 |
7 | 7 | 홀수 | 7×2=14 → 14-9=5 |
5 | 5 | 짝수 | 5 |
9 | 9 | 홀수 | 9×2=18 → 18-9=9 |
3 | 3 | 짝수 | 3 |
5 | 5 | 홀수 | 5×2=10 → 10-9=1 |
4 | 4 | 짝수 | 4 |
합계 = 3+8+8+1+4+6+6+6+5+8+5+5+9+3+1+4 = 82
82 % 10 == 2 → 2이므로 유효하지 않음