개발 이야기3분 읽기

같은 데이터를 일곱 가지로 인코딩하면

한글에는 quoted-printable이 최악이고 영문에는 최선입니다. 인코딩별 크기를 언어별로 재 봤습니다.

바이트를 텍스트로 옮기는 방법이 여럿입니다. 어느 것이 작은지는 무엇을 넣느냐에 따라 뒤집힙니다.

원본을 100으로 두면

입력          원본   hex   b64   b32   b58    QP   url
한글 문장      85B   200   136   160   138   284   295
영문 문장      62B   200   135   168   137   100   126
JSON 조각      50B   200   136   160   138   100   184
무작위 32B     32B   200   138   175   138   206   394

quoted-printable이 영문에서는 100% — 전혀 늘지 않습니다. 한글에서는 **284%**로 셋 중 최악입니다.

URL 인코딩은 더 심합니다. 영문 126%, 한글 295%, 무작위 바이트 394%입니다.

왜 갈리는가

base64·base32·base58은 입력이 무엇이든 고정 비율입니다.

base64  3바이트 → 4자    133%
base32  5바이트 → 8자    160%
base58  가변, 대략      138%
hex     1바이트 → 2자    200%

바이트를 보지 않고 비트만 세므로, 영문이든 한글이든 무작위든 같습니다. 표에서 이 셋의 값이 입력마다 거의 같은 이유입니다.

quoted-printable과 URL 인코딩은 다릅니다. 안전한 문자는 그대로 두고 나머지만 확장합니다.

안전한 바이트  →  1자
그 외         →  3자  (=XX 또는 %XX)

ASCII 영문은 거의 전부 안전한 바이트라 1:1로 지나갑니다. 한글은 UTF-8로 글자당 3바이트이고 그 셋이 모두 비안전이라, 글자 하나가 9자가 됩니다.

그래서 무엇을 고르나

상황 선택 이유
영문 위주 메일 본문 quoted-printable 원문이 그대로 읽힌다
한글·이미지 메일 본문 base64 QP는 세 배가 된다
URL 경로·질의 URL 인코딩 다른 선택지가 없다
JSON에 이진 데이터 base64 표준 관행
대소문자 구분 없는 매체 base32 크지만 대소문자 안 탄다
사람이 옮겨 적을 값 base58 0·O·I·l이 없다
바이트를 눈으로 볼 때 hex 가장 크지만 위치를 센다

base32가 base64보다 큰데도 쓰이는 이유는 대소문자 구분이 없는 곳 때문입니다 — DNS 이름, 파일 시스템, 음성으로 불러 주는 값입니다.

hex가 200%인데도 쓰이는 이유

hex는 표에서 가장 큽니다. 그래도 해시나 바이너리 덤프에는 hex를 씁니다.

위치를 셀 수 있기 때문입니다. hex는 1바이트가 정확히 2자라, 열 번째 바이트가 몇 번째 글자인지 나눗셈 하나로 나옵니다. base64는 3:4 비율이라 그 계산이 안 됩니다.

디버깅에서는 크기보다 이 성질이 큽니다.

압축과 함께 쓰면

한글 문장   85B → gzip 120%
영문 문장   62B → gzip 126%
JSON 조각   50B → gzip 138%

전부 100%가 넘습니다. 짧은 입력에서는 gzip이 원본보다 큽니다 — 헤더와 사전이 본문보다 크기 때문입니다.

gzip이 이득을 내려면 반복이 있어야 하고 분량이 있어야 합니다. 수십 바이트짜리 값을 압축하는 것은 손해입니다.

압축과 인코딩을 겹칠 때는 순서가 결과를 바꿉니다. 반복이 많은 8,800바이트 텍스트로 재 봤습니다.

gzip 만                  103바이트
gzip 먼저 → base64       140바이트
base64 먼저 → gzip       241바이트

압축을 먼저 하는 쪽이 1.7배 작습니다. base64가 3바이트 경계로 자르면서 원본의 반복 주기를 흩뜨려, 압축기가 찾을 패턴이 줄기 때문입니다.

확인 순서

  1. 입력이 ASCII 위주인지 아닌지 먼저 봅니다. 여기서 QP와 base64가 갈립니다
  2. 고정 비율이 필요하면 base64·base32·hex, 내용에 따라 달라져도 되면 QP·URL 인코딩입니다
  3. 짧은 값을 압축하지 않습니다. 헤더가 본문보다 큽니다
  4. 압축과 인코딩을 겹칠 때는 압축을 먼저 합니다
  5. 대소문자를 잃을 수 있는 경로면 base32를 봅니다

tools.onuel.dev에서 같은 문장을 Base64, Base32, Base58에 각각 넣으면 위 비율이 그대로 나옵니다. 영문과 한글의 차이는 Quoted-PrintableURL 인코딩에서 가장 크게 벌어지고, Hex 인코딩은 항상 두 배입니다. 압축을 함께 재려면 Gzip에 같은 값을 넣어 보면 됩니다.

  • #인코딩
  • #Base64
  • #크기