Varint 인코딩 변환기
정수를 LEB128 varint 바이트열로 바꾸고 되읽습니다. 바이트마다 7비트씩 어떻게 나뉘는지 보여 주고, 지그재그 인코딩이 음수를 왜 10바이트에서 1바이트로 줄이는지도 함께 봅니다.
0 ~ 18,446,744,073,709,551,615
2바이트
AC 02
고정 8바이트로 담았을 때보다 6바이트 적습니다.
바이트를 쪼개 보면
| 순서 | 16진 | 2진 | 담은 7비트 | 이어짐 |
|---|---|---|---|---|
| 1번째 | AC | 10101100 | 0101100 | 있음 |
| 2번째 | 02 | 00000010 | 0000010 | 끝 |
값 크기별 바이트 수
| 바이트 | 부호 없음 최대 | 지그재그 절댓값 최대 |
|---|---|---|
| 1바이트 | 127 | ±63 |
| 2바이트 | 16,383 | ±8,191 |
| 3바이트 | 2,097,151 | ±1,048,575 |
| 4바이트 | 268,435,455 | ±134,217,727 |
| 5바이트 | 34,359,738,367 | ±17,179,869,183 |
| 6바이트 | 4,398,046,511,103 | ±2,199,023,255,551 |
| 7바이트 | 562,949,953,421,311 | ±281,474,976,710,655 |
| 8바이트 | 72,057,594,037,927,935 | ±36,028,797,018,963,967 |
| 9바이트 | 9,223,372,036,854,775,807 | ±4,611,686,018,427,387,903 |
| 10바이트 | 18,446,744,073,709,551,615 | ±9,223,372,036,854,775,807 |
사용 방법
- 1숫자를 바이트로 바꿀지, 바이트를 숫자로 되읽을지 고릅니다.
- 2부호 없음(uint)인지 지그재그(sint)인지 정합니다. 음수를 다룬다면 지그재그여야 짧아집니다.
- 3바이트를 쪼갠 표에서 7비트가 어떻게 나뉘고 이어짐 표시가 어디 붙는지 확인합니다.
자주 묻는 질문
값을 7비트씩 끊어 낮은 쪽부터 담고, 각 바이트의 최상위 비트를 "뒤에 더 있다"는 표시로 씁니다. 300은 이진수로 100101100인데, 낮은 7비트 0101100에 이어짐 표시를 붙여 10101100(0xAC), 남은 10에 표시를 끄고 00000010(0x02)이 되어 AC 02가 됩니다. 0부터 127까지는 1바이트, 128부터 16383까지는 2바이트로, 7비트가 늘 때마다 한 바이트씩 늘어납니다.
리틀엔디언이기 때문입니다. 먼저 읽은 바이트가 낮은 자리이고, 뒤에 나오는 바이트일수록 높은 자리입니다. 순서를 거꾸로 알고 있으면 값이 전혀 다르게 나오므로 디버깅할 때 가장 먼저 확인할 부분입니다. 참고로 MIDI에서 쓰는 VLQ는 반대로 높은 자리가 먼저라, 같은 개념이지만 섞어 쓰면 안 됩니다.
음수를 그냥 담으면 최악의 크기가 되기 때문입니다. −1은 64비트가 전부 1이라 varint로 10바이트가 됩니다. 가장 흔한 값 중 하나가 가장 긴 인코딩이 되는 셈입니다. 지그재그는 0을 가운데 두고 양수와 음수를 번갈아 늘어놓아(0→0, −1→1, 1→2, −2→3) 절댓값이 작으면 부호와 상관없이 짧아지게 만듭니다. 식은 (n << 1) ^ (n >> 63)입니다.
sint32만 지그재그를 씁니다. int32는 값을 그대로 varint로 담아서, 음수가 들어가면 매번 10바이트씩 나갑니다. 음수가 자주 나오는 필드에 int32를 쓰는 것이 프로토콜 버퍼에서 가장 흔한 크기 낭비입니다. 반대로 음수가 거의 없다면 int32가 나은데, 지그재그가 양수의 크기를 두 배로 만들어 경계값에서 한 바이트를 더 쓰게 하기 때문입니다.
아닙니다. 한 바이트에 7비트만 실리므로 64비트 값을 담으면 10바이트가 되어, 고정 8바이트보다 오히려 큽니다. 손익분기는 값이 2^56 근처이며 그보다 크면 손해입니다. varint는 실제 자료에 작은 수가 훨씬 많다는 것에 건 도박이라, ID나 타임스탬프처럼 늘 큰 값이 들어가는 필드에는 고정 길이(fixed64)가 낫습니다.
프로토콜 버퍼, WebAssembly 바이너리 포맷, SQLite 레코드, DWARF 디버그 정보가 이 형식을 씁니다. 부르는 이름이 조금씩 달라서 LEB128, Base 128 Varint, VLQ라고도 합니다. 바이너리를 손으로 뜯어볼 때 이 인코딩을 모르면 바이트가 몇 개짜리 필드인지조차 알 수 없어서, 포맷 디버깅에 자주 필요합니다.
알아두면 좋은 점
- 64비트 범위만 다룹니다. 부호 없음은 0 ~ 18,446,744,073,709,551,615, 지그재그는 −9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807입니다.
- 리틀엔디언 LEB128 기준입니다. MIDI의 VLQ는 바이트 순서가 반대이므로 이 결과를 그대로 쓰면 안 됩니다.
- 부호 있는 LEB128(DWARF의 sleb128)은 지그재그가 아니라 부호 확장을 쓰는 별개 방식이라 여기서 다루지 않습니다.
- 입력한 값은 브라우저 안에서만 계산되며 서버로 전송되지 않습니다.
함께 보면 좋은 도구
마지막 검증: 2026년 8월 31일 · 결과는 참고용 추정치입니다.