주민등록번호 검증 코드
C/C++에서 주민등록번호를 검증하는 코드이다.
아래의 함수는 숫자 배열을 가지고 작업하도록 되어있지만 원하는 바에 따라 문자열도 처리가능하다.
bool VerifyJuminNumber( const int number[] )
{
const int tab[] = { 2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4, 5 };
int sum = 0;
for ( int i = 0; i < 12; i++ )
sum += number[ i ] * tab[ i ];
return ( 11 - ( sum % 11 ) ) % 10 == number[ 12 ];
}
가중치를 곱해 더한 합을 11로 나눈 나머지로 검증 숫자(13번째 자리)를 계산하는 표준적인 체크섬 방식이다.
2026년 수정 안내 알고리즘 자체는 정확하고, 2020년 10월 제도 변경 이후에도 체크섬 계산 방식 자체는 그대로 유효하다. 다만 이 변경이 무엇을 바꿨는지, 그리고 애초에 서비스가 이런 검증을 직접 두면 안 되는 이유를 아래에 정리한다.
2020년 10월부터 뒷자리가 임의 부여로 바뀌었다
기존 방식은 뒷자리 6자리 중 앞 두 자리가 출생 신고 지역을 나타내는 지역코드였다. 이 정보로 출생지가 특정되는 문제 때문에, 2020년 10월부터는 지역코드를 없애고 뒷자리 전체(성별 코드 뒤 6자리)를 임의의 숫자로 무작위 부여하도록 바뀌었다.
이 변화 자체는 이 글의 체크섬 알고리즘과 직접적인 충돌은 없다 — 체크섬은 지역코드가 아니라 13자리 전체에 가중치를 곱하는 방식이라, 임의 부여로 바뀌어도 검증 숫자를 계산하는 방식 자체는 유지된다.
그래도 검증에 실패하는 경우들
실무에서 문제가 되는 지점은 알고리즘이 아니라 아래와 같은 것들이다.
- 오래된 목업/테스트 데이터. 예전 방식대로 생성된 임의의 테스트용 주민번호가 체크섬을 만족하지 않는 경우가 흔하다. 이 코드로 검증하면 정상적인 형식의 문자열도 실패로 판정할 수 있다.
- 이 코드는 형식만 검증한다. 체크섬을 통과한다고 해서 실제로 존재하는 번호라는 보장은 없다. 반대로 실제 발급된 번호라도 이 코드가 오류라고 판정하는 경우는 없어야 하지만, 애초에 온라인 서비스에서 주민번호 자체 검증 로직을 직접 두는 것 자체가 지금은 권장되지 않는다.
애초에 이런 자체 검증 로직을 직접 두면 안 된다
지금 기준으로 이야기하자면, 서비스에서 주민등록번호를 직접 저장하고 자체 알고리즘으로 검증하는 방식 자체를 지양해야 한다.
- 개인정보보호법상 주민등록번호는 원칙적으로 수집이 금지되어 있고, 법령에 근거가 있는 경우에만 예외적으로 처리할 수 있다.
- 본인 확인이 필요하다면 NICE평가정보, 코스콤 등 공인 본인확인기관의 CI/DI 연계 서비스를 쓰는 것이 표준적인 방법이다. 실제 존재 여부까지 검증해주고, 원본 번호를 서비스가 직접 들고 있을 필요도 없다.
- 부득이하게 형식만 확인해야 한다면, 이 글의 체크섬 코드는 여전히 유효한 참고 자료로 쓸 수 있다.
댓글 남기기