# QR & 바코드 — QR 코드와 바코드를 오프라인에서 만들기

입력하면 코드가 됩니다. 만드는 데 아무것도 나가지 않습니다.

> 링크나 와이파이, 연락처를 담은 QR 코드를 만들고, EAN-13, UPC-A, Code 128, Code 39 바코드도 만듭니다. SVG나 PNG로 내려받으세요. 전부 브라우저 안에서 일어납니다.

이 페이지는 브라우저 안에서만 동작하는 대화형 도구입니다(https://abox.tools/ko/qr코드-만들기/). 도구에 넘긴 어떤 것도 업로드되지 않습니다. 아래는 이 페이지가 도구에 대해 글로 설명하는 내용 전부입니다. 도구를 쓰려면 이 주소를 여세요.

## 코드와 그 안에 담긴 내용은 **절대 업로드되지 않습니다**. 서버가 아예 없으니까요.

QR 코드는 문자열을 두고 하는 산술입니다. 보낼 파일도, 물어볼 서비스도 없습니다. 모드를 고르고, 버전을 정하고, 리드-솔로몬 오류 정정을 계산하고, 마스크를 씌우고, 바코드의 막대와 그 아래 검사 숫자를 뽑는 일까지 전부 이 페이지 안, 누구나 읽어 볼 수 있는 천 줄 남짓의 JavaScript에서 일어납니다. 이 도구에는 네트워크 기능이 하나도 없고, 그 사실이 다른 페이지보다 여기서 더 중요합니다. 사람들이 QR 코드에 가장 자주 담는 것이 와이파이 비밀번호이기 때문입니다.

- ✗ 업로드 없음
- ✗ 가입 없음
- ✗ 만료 없음
- ✓ 오프라인 동작
- ✓ 오픈 소스

## 아무것도 업로드하지 않고 QR 코드 만드는 방법

1. **코드 종류를 고릅니다.** QR 코드는 무엇이든 담고 휴대폰 카메라가 찾는 것도 그것이라, 누가 따로 말해 주지 않았다면 답은 QR 코드입니다. 바코드는 숫자를 담는데, 어느 것이 필요한지는 그걸 스캔할 쪽이 정합니다. 매장은 EAN-13이나 UPC-A를, 물류 상자는 ITF-14를 원하고, 사내용은 대개 Code 128입니다.
2. **무엇을 담을지 말합니다.** 링크가 가장 흔한 경우이고, 그 위의 칸들이 휴대폰이 알아듣는 다른 형식을 만들어 줍니다. 스스로 접속을 권하는 와이파이, 저장을 권하는 연락처, 이메일, 문자 메시지, 전화번호, 지도상의 위치까지요. 무엇을 고르든 완성된 문자열이 페이지에 표시됩니다. QR 코드가 담는 것은 언제나 그 문자열뿐이니까요.
3. **얼마나 상해도 되는지 정합니다.** 네 단계가 오류 정정을 더 넣거나 덜 넣고, 정정이 많아지면 코드는 더 크고 촘촘해집니다. 화면용이면 L, 보통 종이면 M, 손을 많이 타거나 작게 인쇄되거나 볕 드는 유리창에 붙일 것이면 H입니다. 매일 닦아 내는 메뉴판의 코드라면 Q나 H를 쓸 만합니다.
4. **크기와 여백과 색을 정합니다.** 여백은 코드의 일부입니다. 규격이 요구하는 것은 사방으로 네 모듈의 여백이고, 그것을 잘라 내는 것이 인쇄한 코드가 스캔되지 않는 가장 흔한 이유입니다. 밝은 바탕에 어두운 코드, 그리고 실제로 대비가 있어야 합니다. 스캐너는 둘의 차이를 읽기 때문에 흰 바탕에 옅은 회색은 안 되고, 어두운 바탕에 밝은 코드는 꽤 많은 리더에서 아예 실패합니다.
5. **손에 있는 휴대폰으로 확인합니다.** 천 장을 인쇄하기 전에 화면의 코드를 한 번 스캔해 보세요. 10초면 되고, 미리보기로는 잡을 수 없는 실수를 통째로 잡아냅니다. 이스케이프가 필요했던 문자가 든 와이파이 비밀번호, `https://`가 빠진 링크, 한 자리가 모자란 바코드 번호 같은 것들요.
6. **SVG를 가져갑니다.** 픽셀이 아니라 지시로 적힌 코드라서 어떤 크기로 인쇄해도 뭉개지지 않습니다. 그리고 뭉개진 가장자리야말로 스캐너가 못 읽는 것입니다. 붙여 넣을 곳이 SVG를 받지 않는다면 PNG도 함께 가져가세요. 모듈당 정수 픽셀로 그리기 때문에 그쪽도 가장자리가 흐리지 않습니다.

## 자세한 설명

[남의 휴대폰에서도 스캔되는 QR 코드 만드는 방법](https://abox.tools/ko/가이드/qr코드-만드는-법/): 오류 정정 수준을 무엇으로 고를지, QR 코드 둘레의 흰 여백이 왜 코드의 일부인지, 얼마나 크게 인쇄해야 하는지, 그리고 무료 생성기의 '다이내믹' 코드가 나중에 무엇을 앗아 가는지.

## 상자 속 다른 도구

- [QR과 바코드 스캔](https://abox.tools/ko/qr코드-스캔/): 코드에 카메라를 대거나, 찍어 둔 사진을 올려놓으세요. 읽는 일은 여기서만 일어납니다.
- [해시와 체크섬](https://abox.tools/ko/체크섬-확인/): 받은 파일을 배포처가 적어 둔 숫자와 맞춰 봅니다. 어디로도 보내지 않고요.
- [비밀번호·패스프레이즈 생성기](https://abox.tools/ko/비밀번호-생성기/): 여기서, 본인 브라우저가 만듭니다. 어디로도 보내지 않고, 저장하지 않고, 기록도 남기지 않습니다.
- [JSON 포매터](https://abox.tools/ko/json-포맷터/): JSON, XML, HTML, CSS, YAML을 정렬하거나 변환합니다. 남의 서버에 붙여 넣는 것은 없습니다.

## 자주 묻는 질문

### 제가 입력한 것이 어딘가로 전송되나요?

아닙니다. QR 코드는 문자열을 두고 하는 산술이고, 그 산술은 내 기기에서 도는 내 브라우저가 합니다. 이 도구에는 네트워크 기능이 하나도 없어서 무언가를 가져오지도, 보내지도 않습니다. 이 페이지의 `Content-Security-Policy`에 연결해도 되는 주소가 전부 적혀 있는데, 그중 이 사이트 것은 하나도 없습니다. 다른 페이지보다 여기서 더 값어치 있는 사실이지요. 사람들이 QR 코드에 가장 자주 담는 것이 와이파이 비밀번호이기 때문입니다.

### 이 코드는 만료되거나 나중에 멈추나요?

아닙니다. 그럴 수가 없습니다. 입력한 것이 곧 코드가 담는 것이라, 스캔하면 언제까지나 정확히 그 문자열이 나옵니다. 만료되는 코드는 안에 남의 주소가 든 것들입니다. "다이내믹" QR 코드는 생성기 서버의 링크를 담고 있고 그 서버가 원래 주소로 넘겨 줍니다. 그러니 그쪽이 스캔을 모두 셀 수 있고, 목적지를 바꿀 수도 있으며, 체험 기간이 끝나면 꺼 버릴 수도 있습니다. 여기서는 아무것도 거쳐 가지 않습니다.

### 무료인가요? 상업적으로 써도 되나요?

무료이고, 계정도 워터마크도 개수 제한도 없으며, 결과를 제품이나 포스터, 가게 앞에 써도 됩니다. QR Code는 덴소 웨이브의 등록 상표이지만, 코드를 쓰는 사람에게 권리를 행사하지 않겠다고 밝혀 두었습니다. 규격은 ISO/IEC 18004으로 공개되어 있어 누구나 자유롭게 구현할 수 있고, 이 페이지가 하는 일이 바로 그것입니다. 이 사이트는 광고로 유지됩니다.

### 오류 정정 수준은 무엇을 고르면 되나요?

특별한 이유가 없다면 M입니다. L은 코드가 가장 작고 화면에서는 충분합니다. M은 보통 다루기를 견딥니다. Q와 H는 작게 인쇄하거나 코팅하거나 유리창에 붙이거나 로고로 일부를 가릴 코드를 위한 것입니다. 한 단계 올릴 때마다 검사 데이터가 늘어나서, 같은 글자 수라도 더 큰 심벌이 필요합니다. L에서 H로 가면 같은 문자열에 대해 모듈 수가 대략 두 배가 됩니다.

### QR 코드에는 얼마나 담을 수 있나요?

가장 큰 177모듈 정사각형에서 숫자만이면 7,089자, 대문자와 숫자면 4,296자, 그 밖의 바이트면 2,953바이트입니다. 그것도 오류 정정이 가장 약할 때이고, 가장 강할 때는 그 3분의 1쯤입니다. 현실적인 한계는 형식이 아니라 스캐너입니다. 몇백 자를 넘기면 모듈이 너무 작아져 보통 휴대폰 카메라가 팔 길이에서 분간하지 못합니다. 코드가 길다는 것은 보통 그 안에 짧은 링크가 들어가야 한다는 신호입니다.

### 링크를 소문자로 쓰면 왜 코드가 커지나요?

QR 코드에는 대문자와 숫자를 두 글자당 11비트로 담는 모드가 있는데, 소문자에는 그런 모드가 없어서 글자당 8비트가 들기 때문입니다. `HTTPS://EXAMPLE.COM/PAGE`라고 쓴 URL은 같은 URL을 소문자로 쓴 것보다 3분의 1쯤 작아질 수 있습니다. 스킴과 호스트는 대소문자를 가리지 않으므로 크게 외쳐도 크기 말고는 달라지는 것이 없습니다. 호스트 뒤의 경로는 가리니 그건 그대로 두세요.

### QR 코드를 만드는 것 말고 읽을 수도 있나요?

이 페이지는 못 하지만 옆 페이지가 합니다. [리더](https://abox.tools/ko/qr코드-스캔/)가 사진이나 스크린숏, 또는 카메라를 받아 그 안의 문자열을 돌려줍니다. 그리는 것보다 훨씬 큰 일입니다. 이미지 속에서 심벌을 찾고, 찍힌 각도를 보정하고, 손상된 부분을 복구하는 세 가지는 이 페이지에는 없는 문제니까요. 그래서 여기 버튼이 아니라 별도의 도구입니다. 조건은 나머지와 같습니다. 아무것도 올라가지 않고, 카메라 화면도 남기지 않습니다.

### 여백은 왜 필요하고, 줄여도 되나요?

QR 코드 둘레의 빈 공간은 코드의 일부입니다. 리더는 그것으로 심벌이 어디서 끝나는지 알아내고, 규격은 사방 네 모듈을 요구합니다. 바코드는 열 모듈쯤을 원하고요. 여기서 0으로 만들 수 있고 그림은 더 깔끔해 보이겠지만, 그러면 꽤 많은 스캐너가 아예 보지 못합니다. 특히 배경이 복잡할 때 그렇습니다. 자리가 문제라면 여백을 깎지 말고 코드를 작게 만드세요.

### 어떤 바코드가 필요한가요?

스캔할 사람이 달라는 것입니다. EAN-13은 북미 밖의 유통 바코드이고 UPC-A가 북미의 것인데, 둘 다 GS1에서 발급받은 번호가 필요합니다. 그 번호가 제품만이 아니라 회사를 가리키기 때문입니다. EAN-8은 작은 포장을 위한 짧은 판본입니다. ITF-14는 물류 상자에 붙습니다. Code 128과 Code 39는 숫자뿐 아니라 글자도 담고 등록이 전혀 필요 없어서, 자산이나 선반, 작업 지시서 같은 사내용에는 이쪽이 맞습니다.

### 검사 숫자가 무엇이고, 도구는 왜 그것을 붙였나요?

유통 바코드의 마지막 숫자로, 앞의 숫자들에서 계산해 냅니다. 스캐너가 잘못 읽은 것과 제대로 읽은 것을 구별할 수 있도록요. EAN-13은 열두 자리를 받아 열세 번째를 계산하고, UPC-A는 열한 자리를 받아 열두 번째를 계산합니다. 짧은 번호를 입력하면 이 페이지가 붙여 줍니다. 전체 번호를 입력하면 주신 것을 검사하고, 조용히 고치는 대신 거부합니다. 잘못 입력한 숫자를 말없이 고치면 남의 제품으로 스캔되는 라벨이 되니까요.

### QR 코드 한가운데 로고를 넣을 수 있나요?

여기서는 안 되지만, 다른 데서 그게 되는 이유는 알아 둘 만합니다. 가능하게 해 주는 것은 오류 정정입니다. H 수준에서는 모듈의 30%쯤이 망가져도 코드가 읽히므로, 파인더 패턴이 없는 한가운데를 그보다 좀 덜 덮는 로고는 복구 가능한 손상이 됩니다. H 수준으로 만든 코드를 이미지 편집기에 넣고, 로고를 면적의 5분의 1 아래로 두고, 믿지 말고 실제 휴대폰으로 시험해 보세요.

### 왜 PNG보다 SVG가 나은가요?

코드는 결국 가장자리이고, PNG에는 그 가장자리를 만들 픽셀 수가 정해져 있기 때문입니다. 확대하면 모든 가장자리가 뭉개지는데, 뭉개진 가장자리야말로 스캐너가 힘들어하는 것입니다. 1200dpi 인쇄기에 512픽셀 PNG를 주는 것은 그 차이를 지어내라고 시키는 셈이에요. SVG는 사각형을 지시로 적어 둔 것이라 명함이든 옥외 광고판이든 선명하게 인쇄됩니다. 여기 PNG는 모듈당 정수 픽셀로 그리는데, PNG로서는 그게 최선입니다.

### 오프라인에서도 되나요?

됩니다. 페이지를 한 번 불러온 다음 인터넷을 끊어도 계속 동작합니다. 아무것도 업로드되지 않는다는 가장 간단한 증명이기도 하고요. 입력한 글자를 어딘가로 보내서 코드를 그려 오는 도구라면 선을 뽑는 순간 멈춰 버릴 테니까요.

## 이 약속을 직접 확인하는 방법

- **입력한 것은 나갈 곳이 없습니다.** 이 페이지가 연결해도 되는 주소는 Content-Security-Policy에 모두 적혀 있는데, 그중 이 사이트 것은 하나도 없습니다. 와이파이 비밀번호가 모일 만한 수신 지점이 없고, 설령 있더라도 거기로 무언가를 보낼 코드가 없습니다.
- **여기서는 아무것도 가져오지 않습니다.** `src/` 어디에도 `fetch`도, `XMLHttpRequest`도, `sendBeacon`도 없습니다. 코드는 문자열에서 산술로 만들어져 SVG로 그려집니다. 이 페이지 안에서, 내 기기에서요.
- **이 코드는 우리를 가리키지 않습니다.** 입력한 것이 곧 코드가 담는 것입니다. 여러 무료 생성기가 자기네 사이트 링크가 든 코드를 돌려주고 거기서 원래 주소로 넘겨 줍니다. 그러면 스캔 하나하나가 그쪽에서 세어지고, 그쪽이 도메인 값을 그만 내거나 무료 요금제가 끝났다고 판단하는 날 코드가 멈춥니다. 여기서는 줄이지도, 넘기지도, 추적하지도 않습니다. 페이지에 보이는 문자열이 그림 속 문자열입니다.
- **PNG는 화면에 있는 그 SVG에서 만들어집니다.** 내려받는 것은 미리보기와 어긋날 수도 있는 두 번째 렌더링이 아닙니다. 같은 마크업을 브라우저에 넘겨 캔버스에 그립니다. 아무 데도 연결하지 않고 그렇게 할 수 있는 이유이기도 합니다. 가져올 글꼴도, 그 안에 넣을 이미지도 없으니까요.
- **구글이 불러오는 것과, 구글에게 주지 않는 것.** 광고와 측정 스크립트는 구글에서, 후원 버튼은 Buy Me a Coffee에서 옵니다. 어느 쪽에도 입력한 내용은 넘어가지 않습니다. 문자열을 코드로 바꾸는 코드는 한 줄도 빠짐없이 이 출처에서 제공되고 저장소에 공개되어 있습니다.
- **오프라인에서도 동작합니다.** 네트워크를 끊어도 도구는 그대로입니다. 애초에 네트워크를 쓰는 단계가 없었으니까요. 가장 간단한 증거입니다.

**직접 확인해 보세요.** 위에 적은 어느 것도 그냥 믿으실 필요는 없습니다. 이 페이지는 저장소 안의 템플릿과 설정을 빌드 스크립트가 찍어 낸 결과이고, 그 스크립트는 누구나 읽고 직접 돌려 볼 수 있습니다. 결과물은 `dist` 브랜치에 그대로 올라가 있고요. 그래서 실제로 제공되는 파일과 소스를 빌드한 결과를 나란히 놓고 비교해 보실 수 있습니다: https://github.com/A-Box-of-Tools/website

먼저 읽어 볼 파일을 꼽자면, Content-Security-Policy는 `config/site.toml`, QR 코드 자체는 `src/qr-encode.js`와 `src/qr.js`에 있습니다. 한쪽에 모드와 버전과 블록이, 다른 쪽에 패턴과 마스크와 포맷 비트가 들어 있고요. 오류 정정은 `src/gf256.js`, 줄무늬 쪽은 `src/barcode.js`에 있습니다.
