개발 이야기4분 읽기

QR 코드가 커지는 이유

같은 200자가 오류 정정 레벨에 따라 45×45가 되기도 61×61이 되기도 합니다. 버전·모드·EC 레벨이 크기를 어떻게 결정하는지 정리했습니다.

QR 코드를 만들다 보면 내용이 조금 늘었을 뿐인데 격자가 갑자기 촘촘해집니다. 크기를 정하는 요소는 세 가지입니다 — 데이터 길이, 인코딩 모드, 오류 정정 레벨.

버전과 모듈

QR 코드의 크기 단위는 버전입니다. 버전 1이 21×21 모듈이고, 한 단계 올라갈 때마다 가로세로 4모듈씩 커집니다. 최대는 버전 40, 177×177입니다.

영문 대문자를 길이별로 넣어 보면 이렇게 올라갑니다.

데이터 버전 모듈
10자 1 21×21
25자 2 25×25
50자 3 29×29
100자 5 37×37
200자 8 49×49
400자 12 65×65
800자 18 89×89

버전은 연속적으로 오르지 않습니다. 50자에서 100자로 늘 때 버전이 3에서 5로 건너뜁니다. 각 버전에 정해진 용량이 있고, 넘치면 다음 버전으로 통째로 넘어갑니다.

오류 정정이 용량을 먹는다

QR 코드는 일부가 가려져도 읽히도록 데이터와 함께 복원용 코드워드를 넣습니다. 레벨이 네 개입니다.

같은 200자를 레벨만 바꿔 인코딩하면 이렇게 갈립니다.

레벨 복원 가능 비율 버전 모듈
L 약 7% 7 45×45
M 약 15% 8 49×49
Q 약 25% 10 57×57
H 약 30% 11 61×61

L과 H의 차이가 버전 4단계, 모듈로는 45×45와 61×61입니다. 면적으로는 1.8배입니다.

거꾸로 버전을 고정하고 보면 들어가는 양이 이렇게 달라집니다.

버전 5(37×37)에 들어가는 영문 대문자
  EC L : 154자
  EC M : 122자
  EC Q :  87자
  EC H :  64자

가운데에 로고를 넣으려면 H가 필요합니다. 로고가 데이터 영역을 가리는데, 그 손실을 오류 정정이 메워야 하기 때문입니다. 가릴 면적이 전체의 30%를 넘지 않도록 하고, 만든 뒤 실제 기기로 읽어 확인해야 합니다.

모드에 따라 글자당 비트가 다르다

QR에는 네 가지 인코딩 모드가 있고, 내용에 따라 자동으로 골라집니다.

모드 글자당 비트 쓸 수 있는 문자
숫자 약 3.33 0-9
영숫자 5.5 0-9 A-Z공백 $ % * + - . / :
바이트 8 이상 임의 바이트 (UTF-8이면 한글은 3바이트)
한자 13 Shift_JIS 범위

같은 100자라도 결과가 크게 갈립니다.

내용 버전 모듈
숫자 100자 3 29×29
영문 대문자 100자 5 37×37
소문자 포함 100자 6 41×41
한글 100자 13 69×69

영숫자 모드에는 소문자가 없습니다. 소문자가 하나라도 섞이면 전체가 바이트 모드로 떨어져 글자당 5.5비트에서 8비트로 올라갑니다. URL을 QR로 만들 때 호스트를 대문자로 적는 관행이 여기서 나왔습니다 — HTTPS://EXAMPLE.COM/PATH는 영숫자 모드에 들어가고, 호스트는 대소문자를 구분하지 않으므로 동작에 문제가 없습니다. 다만 경로는 대소문자를 구분하므로 함께 바꾸면 안 됩니다.

한글 100자는 UTF-8로 300바이트라 버전 13까지 갑니다. 인쇄물에 넣을 때 이 차이가 실제 크기로 나타납니다.

URL 하나를 넣어 보면

https://tools.onuel.dev/ko/generator/qr-code   (44자)
  EC M -> 버전 4, 33×33
  EC H -> 버전 5, 37×37

짧은 URL은 레벨을 올려도 큰 부담이 없습니다. 반대로 쿼리스트링에 토큰이 붙은 200자짜리 URL은 위 표대로 커집니다. 인쇄물에 넣을 QR이라면 짧은 주소로 리다이렉트하는 편이 낫습니다.

인쇄와 스캔

  • 최소 모듈 크기 — 인쇄물에서 한 모듈이 최소 0.4mm 정도는 되어야 일반 카메라로 읽힙니다. 버전 18(89×89)을 이 크기로 인쇄하면 약 36mm가 필요하고, 여백까지 더하면 42mm입니다
  • 여백(quiet zone) — 사방에 4모듈 이상의 빈 공간이 필요합니다. 배경 이미지에 바짝 붙이면 인식률이 떨어집니다
  • 명암 — 어두운 모듈과 밝은 배경의 대비가 필요합니다. 색을 쓰려면 어두운 쪽을 충분히 어둡게 합니다. 반전(밝은 모듈, 어두운 배경)은 지원하지 않는 리더가 있습니다
  • 곡면·비스듬한 각도 — 정렬 패턴이 어느 정도 보정하지만 한계가 있습니다

확인 순서

  1. 내용을 줄일 수 있는지 먼저 봅니다. 버전을 낮추는 가장 확실한 방법입니다
  2. URL이라면 대문자로 바꿔 영숫자 모드에 들어가는지 확인합니다. 경로의 대소문자는 그대로 둡니다
  3. 로고를 얹을 것이면 EC 레벨을 H로 올리고, 가리는 면적을 30% 아래로 유지합니다
  4. 출력물 크기에서 모듈 하나가 몇 mm인지 계산합니다. 0.4mm 아래로 내려가면 버전을 낮추거나 인쇄를 키웁니다
  5. 실제 기기로 읽어 봅니다. 여러 대, 어두운 조명, 비스듬한 각도에서 확인합니다

tools.onuel.devQR 코드 생성기에서 오류 정정 수준을 골라 SVG나 PNG로 받을 수 있습니다. 같은 내용을 L과 H로 각각 만들어 보면 격자 밀도 차이가 바로 보입니다. 인코딩이 브라우저 안에서 실행되므로 Wi-Fi 비밀번호나 비공개 링크를 넣어도 기기 밖으로 나가지 않습니다.

  • #QR코드
  • #인코딩