로또 용지 QR 인식 성공이 0건이었던 이유: 기록하지 않은 경로는 실패처럼 보인다
로또 앱 주간 보고에서 QR 화면을 연 사람은 19명인데 인식 성공은 0건이었습니다. 스캐너가 고장 난 게 아니라, 진짜 용지 QR 이 지나가는 경로에 기록이 하나도 없었습니다. 측정 구멍을 찾은 과정, 같은 기능 앱 4개와 비교한 결과, 스캔 엔진을 번들로 바꾼 이유, 고친 뒤 1주일 숫자를 정리합니다.
19명이 열었는데 성공 0건
로또 당첨번호 앱에는 용지의 QR 을 찍어 당첨 결과를 보는 화면이 있습니다. 10월 초 주간 보고에서 이 화면을 연 사람은 19명이었고, GA4 의 인식 성공 기록은 0건이었습니다.
19명 중 한 명도 읽지 못했다면 스캐너가 고장 난 것입니다. 그런데 직접 찍어 보면 잘 읽혔습니다. 숫자와 손에서 본 결과가 맞지 않아서, 스캐너보다 기록하는 코드를 먼저 의심했습니다.
진짜 용지 QR 은 기록 없이 앱을 떠났다
QR 을 읽은 뒤 처리하는 코드를 다시 읽어 보니 경로가 둘이었습니다.
- 읽은 값이 URL 이면 외부 브라우저로 넘깁니다. 기록은 없습니다.
- URL 이 아니면 앱 안의 파서가
LOTTO;ROUND=…;NUMBERS=…형식으로 해석합니다. 시도와 성공 기록은 이쪽에만 있었습니다.
실제 로또 용지의 QR 은 전부 URL 입니다. LOTTO;ROUND= 형식은 개발 초기에 예시로 만든 것이고, 이런 QR 이 찍힌 용지는 없습니다. 결국 진짜 용지를 찍은 사람은 모두 첫 번째 경로로 브라우저에 넘어갔고, 기록이 남는 두 번째 경로는 아무도 지나가지 않았습니다. 「성공 0건」은 실패가 아니라 측정 구멍이었습니다.
용지 QR 의 생김새
고치기 전에 실제 용지 QR 의 형식부터 확인했습니다.
http://qr.dhlottery.co.kr/?v=1245q061415182834q…n000000000000…
v=뒤 4자리는 회차입니다.- 이어서 게임마다 글자 하나와 숫자 12자리가 붙습니다. 글자는
q자동,s반자동,m수동,n빈칸이고, 숫자 12자리는 두 자리씩 번호 6개입니다. - 끝에 용지 일련번호가 붙습니다.
v가pd로 시작하면 연금복권 용지입니다.
예전 용지에 찍힌 m.dhlottery.co.kr/?v= 주소도 지금 열어 보면 307 로 qr.dhlottery.co.kr 로 넘어가서 정상적으로 결과가 나왔습니다(10월 15일 확인).
기록부터 넣었다
어디서 끊기는지 알아야 하니, 앱 동작을 바꾸기 전에 모든 갈래에 기록을 넣었습니다.
| 갈래 | 기록 |
|---|---|
| 동행복권 로또 주소 | 성공 + 주소 모양 |
| 연금복권 주소 | 성공 + 주소 모양 |
| 다른 주소 | 실패 + 도메인 |
| 로또 QR 이 아님 | 실패 |
| 카메라 권한 거부 | 실패 |
| 아무것도 못 읽고 나감 | 실패(no_read) |
주소 모양은 숫자를 모두 9 로 바꿔서 남깁니다. 용지 번호는 개인이 산 복권이라 분석 도구에 그대로 보내지 않고, 형식이 맞는지만 알 수 있게 했습니다.
lotto_url:qr.dhlottery.co.kr/?v=9999q999999999999q999999999999…
같은 기능 앱 4개는 어떻게 하나
QR 로 당첨을 확인하는 다른 앱 4개를 설치해서 APK 를 열고 QR 처리 부분을 봤습니다.
- 4개 모두 스캔한 뒤 앱 밖으로 나가지 않았습니다. 셋은
v값을 앱 안에서 직접 잘라 당첨번호와 맞춰 보고, 하나는 동행복권 결과 페이지를 앱 안 웹뷰로 엽니다. - 외부 브라우저로 넘기는 건 우리 앱뿐이었습니다. 브라우저로 넘어간 사람은 결과를 본 뒤 앱으로 돌아오지 않을 수 있고, 앱은 그 사람이 결과를 봤는지 알 수 없습니다.
- 셋은 ML Kit 바코드 스캐너의 번들 버전을 쓰고 있었고, 우리는 번들이 아닌 버전이었습니다.
번들이 아닌 스캔 엔진의 함정
ML Kit 바코드 스캐너에는 두 가지 버전이 있습니다. 번들 버전은 인식 모델이 APK 안에 들어 있고, 번들이 아닌 버전은 모델을 Google Play 서비스가 따로 내려받습니다.
공식 문서를 다시 읽어 보니, 번들이 아닌 버전은 앱을 Play 스토어에서 설치할 때만 모델을 미리 받아 둡니다. 다른 경로로 설치하면 첫 스캔 때 받기 시작하고, 받기 전에 들어온 요청에는 「결과 없음」을 돌려줍니다. 사용자 눈에는 카메라에 QR 을 비춰도 아무 반응이 없는 화면입니다.
이 앱은 Play 스토어 말고 다른 스토어에도 올립니다. 그래서 번들 버전으로 바꿨습니다. APK 가 약 2.4MB 커지지만 설치 경로와 상관없이 첫 스캔부터 읽습니다. 번들 버전에 든 네이티브 라이브러리가 16KB 페이지 정렬인지도 확인했습니다.
함께 바꾼 것은 다음과 같습니다(10월 15일 1.0.76).
- 동행복권 결과 페이지를 외부 브라우저 대신 앱 안 웹뷰로 엽니다.
- 같은 QR 이 연달아 읽혀 결과 페이지가 여러 번 열리지 않게 막았습니다.
- 스캐너 오류와 결과 페이지 로딩 실패도 이유와 함께 기록합니다.
고친 뒤 1주일
1.0.76 부터 10월 22일까지 QR 화면 기록입니다.
| 항목 | 사용자 | 횟수 |
|---|---|---|
| QR 화면 시도 | 33명 | 83회 |
| 성공(동행복권 주소) | 5명 | 16회 |
| 못 읽고 나감 | 21명 | 41회 |
| 카메라 권한 거부 | 3명 | 9회 |
| 다른 주소 | 1명 | 1회 |
성공이 처음으로 잡혔습니다. 1.0.76 에서 성공한 주소 모양은 모두 예전 주소(m.dhlottery.co.kr)였습니다. 예전 용지도 인식되고 있습니다.
아직 모르는 것
- 못 읽고 나감이 21명으로 가장 많습니다. 이것이 「찍었는데 못 읽은 것」인지 「화면만 열어 보고 나간 것」인지는 지금 기록으로는 구분되지 않습니다. 화면에 머문 시간과 카메라가 QR 비슷한 것을 잡았는지까지 남겨야 나눌 수 있습니다.
- 다른 주소로 잡힌 1건은
qr.645lotto.net이었습니다(1.0.76 사용자). 예전 로또 사이트 주소로, 비교한 앱 중 하나는 도메인을 따지지 않고v값만 해석해서 이 주소도 읽습니다. 1.0.76 은 동행복권 도메인만 로또 주소로 봐서 이 사람은 「로또 QR 이 아님」 안내를 받았습니다. 이 도메인은 10월 17일 1.0.78 에서 로또 주소 목록에 넣어, 지금 판은 같은 방식으로v값을 읽습니다.
정리
- 성공률이 0이면 실패 이유보다 먼저 성공이 기록되는 경로를 실제 사용자가 지나가는지 확인합니다. 예시 데이터로만 시험한 코드에 기록이 몰려 있을 수 있습니다.
- 외부 앱으로 넘기는 갈래는 기록이 끊기는 지점입니다. 넘기기 전에 한 줄이라도 남깁니다.
- 기록에 개인이 산 번호 같은 값이 들어간다면 모양만 남깁니다.
- ML Kit 번들이 아닌 버전은 Play 스토어 설치가 아니면 첫 스캔이 비어 있을 수 있습니다. 다른 스토어에도 배포한다면 번들 버전을 검토합니다.
- 숫자가 생긴 뒤에도 「못 읽음」과 「안 찍음」이 섞여 있으면 다음 판에서 나눌 기록을 더 넣어야 합니다.
이 글에 나온 앱은 로또 당첨번호·명당 판매점 앱(Google Play) 입니다.