카드 번호 형식을 한 문장으로 줄이면 세 토막의 조합입니다. 어느 발급사인지 알려 주는 앞부분, 계정을 가리키는 가운데 부분, 그리고 오타를 잡는 마지막 한 자리입니다. 그런데 이 단순한 구조를 실제 화면에 옮기면 곧바로 질문이 생깁니다. 왜 어떤 카드는 16자리이고 어떤 카드는 15자리인지, 앞의 두 자리만 보고 카드사를 알 수 있는지, 입력 칸은 언제 자릿수를 구분해 주어야 하는지 같은 것들입니다. 이 글은 그 질문들에 차례로 답합니다.
카드 번호는 어떻게 읽어야 할까?
첫 토막은 발급 기관 식별 번호입니다. 카드 번호 맨 앞에 오며, 어느 카드사가 발급했는지와 그 카드가 어떤 종류인지를 드러냅니다. 과거에는 발급사 단위의 짧은 번호였지만 지금은 8자리까지 쓰이는 경우가 있어, 앞 몇 자리만 보고 단정하지 않는 편이 안전합니다.
두 번째 토막은 계정 번호입니다. 발급사가 개별 계좌를 구분하려고 붙이는 부분이며, 길이는 전체 자릿수에서 앞뒤를 뺀 만큼입니다. 이 부분에는 규칙이 거의 없어서, 겉으로 보아서는 아무 정보도 읽어 낼 수 없습니다.
세 번째 토막은 마지막 한 자리입니다. 앞의 모든 자릿수를 계산해 넣는 검산 숫자이며, 계산 방법은 공개되어 있습니다. Luhn 알고리즘에서 그 계산을 손으로 따라 해 볼 수 있습니다.
| 토막 | 위치 | 하는 일 |
|---|---|---|
| 발급 기관 식별 번호 | 맨 앞 | 카드사와 카드 종류 구분 |
| 계정 번호 | 가운데 | 개별 계좌 구분 |
| 검산 숫자 | 맨 뒤 한 자리 | 입력 오류 탐지 |
자릿수는 표준이 정할까 카드사가 정할까
결론부터 말하면 둘 다입니다. 국제 표준은 번호가 가질 수 있는 전체 범위와 구조를 정합니다. 앞부분이 발급 기관을 가리키고 마지막 한 자리가 검산 숫자라는 틀, 그리고 번호가 가질 수 있는 최대 길이가 여기에 해당합니다. 이 틀 안에서 각 카드사가 자기 계좌 체계에 맞는 길이와 시작 대역을 골라 씁니다.
그래서 표준을 읽었다고 해서 특정 카드의 길이를 알 수는 없습니다. 표준은 한계를 정하고, 카드사는 그 한계 안에서 선택합니다. 검증 로직을 만들 때 이 둘을 구분하지 않으면, 표준의 최대 길이를 모든 카드의 길이로 착각하거나 반대로 카드사별 규칙을 표준이 정한 것처럼 굳혀 버립니다.
왜 자릿수가 카드사마다 다를까
자릿수가 다른 것은 설계상의 선택입니다. 국제 표준은 카드 번호의 최대 길이를 19자리로 두고, 그 안에서 각 카드사가 자기 번호 체계에 맞는 길이를 정하도록 합니다. 실제로 널리 쓰이는 길이는 13자리부터 16자리 사이에 몰려 있지만, 19자리까지 허용된다는 사실을 모르면 나중에 새 대역이 등장했을 때 검증 로직이 조용히 거부하게 됩니다.
그래서 자릿수를 하나로 고정하는 검증은 위험합니다. 열여섯 자리가 아니면 틀렸다고 판단하는 코드는 정상적인 카드를 막아 버립니다.
앞자리 숫자는 무엇을 알려 줄까
카드 번호의 첫 자리는 산업 분류를 뜻합니다. 이 규칙은 공개된 번호 체계이며, 어느 카드사가 어느 대역을 쓴다는 정보도 함께 공개되어 있습니다.
- 4는 Visa 대역으로 시작합니다.
- 5와 2 계열은 Mastercard가 사용합니다.
- 3은 여행과 엔터테인먼트 계열로, American Express와 Diners, JCB가 나눠 씁니다.
- 6은 Discover와 유니온페이가 사용합니다.
- 1과 2의 일부 대역, 7, 8, 9는 항공이나 석유, 통신, 국가 배정 같은 다른 용도로 나뉘어 있습니다.
첫 자리만으로 카드사를 확정할 수는 없습니다. 같은 3으로 시작해도 뒤 자리에 따라 카드사가 갈리고, 6으로 시작하는 대역도 여러 카드사가 나눠 씁니다. 카드사 판별은 몇 자리 조합을 비교해야 끝납니다.
앞의 몇 자리를 봐야 카드사를 알 수 있을까
한 자리로는 알 수 없고, 여섯 자리면 대부분 갈립니다. 첫 자리는 산업 분류만 알려 주기 때문에, 같은 3으로 시작하는 카드가 여러 카드사에 흩어져 있고 6으로 시작하는 대역도 마찬가지입니다. 그래서 판별은 몇 자리 조합을 공개된 대역표와 비교하는 방식으로 이뤄지며, 대역에 따라 필요한 자릿수가 달라집니다.
비교할 때는 긴 대역을 먼저 보는 편이 안전합니다. 짧은 대역을 먼저 검사하면 그 안에 속하는 긴 대역이 가려져서 엉뚱한 카드사로 판정됩니다. 대역표가 겹치는 구간을 어떻게 정렬해 두었는지가 판별 정확도를 좌우합니다.
판별에 필요한 자릿수를 정했다면, 그 판별이 화면에서 어떻게 드러나는지도 함께 보겠습니다. 결제 화면에서 번호를 입력하면 카드사 로고가 곧바로 바뀌는 것을 볼 수 있습니다. 이 판단은 앞자리 조합을 공개된 대역표와 비교해서 이뤄집니다. 대역표는 여러 카드사가 공유하는 구간이 있어서, 비교 순서를 정해 두지 않으면 엉뚱한 로고가 뜨기도 합니다.
대역이 겹치는 지점을 테스트하지 않으면 이 문제를 놓칩니다. 카드사별 대역과 자릿수 차이는 카드사별 테스트 카드 번호에 정리해 두었습니다.
입력 칸에서 자릿수를 어떻게 다룰까?
사용자는 보통 카드에 인쇄된 모양 그대로, 네 자리씩 끊어 입력합니다. 반면 시스템이 다루기에 좋은 형태는 구분 기호가 없는 연속된 숫자입니다. 이 둘을 같이 만족시키는 방법은 입력을 받으면서 화면에만 구분 기호를 보여 주고, 값 자체는 숫자만 유지하는 것입니다.
입력 처리에서 자주 나오는 실수는 다음과 같습니다.
- 구분 기호를 값의 일부로 저장해, 나중에 자릿수 계산이 어긋나는 경우
- 붙여넣기로 들어온 공백과 하이픈을 걷어내지 않는 경우
- 뒷자리를 하나씩 지울 때 구분 기호가 남아 커서가 튀는 경우
- 자릿수를 넘겨 입력해도 잘라 내지 않아 화면이 밀리는 경우
개발자를 위한 메모: 정리와 표시를 갈라 두라
검증과 저장은 정리된 값으로, 표시는 사람이 읽기 좋은 형태로 나누는 것이 기본입니다. 입력을 받는 즉시 숫자만 남긴 값을 별도로 들고 있고, 화면에는 그 값에서 네 자리마다 구분 기호를 끼워 다시 그리는 방식이 가장 단순합니다.
자릿수 검사는 상한과 하한을 함께 두는 편이 좋습니다. 하한만 두면 긴 입력이 그대로 통과하고, 상한만 두면 짧은 입력이 뒤 단계에서 엉뚱한 오류를 냅니다. 카드사별 허용 길이를 표로 관리하고, 표에 없는 대역은 통과시키되 별도로 로그를 남기는 전략도 실무에서 자주 쓰입니다. 검증 순서 전반은 코드로 카드 번호 검증하기에서 이어서 다룹니다.
다음 단계
지금 쓰는 검증 로직에 자릿수가 하나로 고정되어 있다면, 먼저 카드사별 길이표를 만들어 그 표를 기준으로 바꾸는 것부터 시작해 보세요. 생성기에서 카드사를 바꿔 가며 여러 자릿수의 번호를 만들어 두면, 새 규칙이 기존 입력을 막지 않는지 빠르게 확인할 수 있습니다. 이때 만들어지는 번호는 구조적으로 유효하지만 실제로 발급된 적이 없어 결제에 쓸 수 없습니다.