zlib으로 압축해 Base64로 인코딩하는 방법
- 텍스트를 입력하거나 붙여넣거나, 파일을 놓으세요.
- 형식은 zlib (deflate) 로 시작합니다. 받는 쪽이 압축 스트림만 원하면 Raw deflate로, 아니면 gzip으로 바꾸세요.
- 필요하면 URL-safe (- _) 나 76자에서 줄 바꿈을 켜세요.
- 출력 복사를 누르거나, Base64
.txt또는 바이너리.zz/.deflate파일을 다운로드하세요.
바꾸기는 출력을 압축 해제 쪽으로 보내 왕복 변환을 확인합니다.
같은 텍스트, 세 가지 래퍼
Hello, world!(13바이트)를 기본 수준으로 압축하면 다음과 같습니다.
| 형식 | 바이트 | Base64 |
|---|---|---|
| raw deflate | 15 | 80jNycnXUSjPL8pJUQQA |
| zlib | 21 | eJzzSM3JyddRKM8vyklRBAAgXgSK |
| gzip | 33 | H4sIAAAAAAAAA/NIzcnJ11Eozy/KSVEEAObG5usNAAAA |
deflate 스트림은 세 가지 모두에서 같은 15바이트인데도 Base64가 달라 보이는 것은 2바이트와 10바이트 헤더 때문에 각 바이트가 3바이트 그룹 안에서 놓이는 위치가 밀리기 때문입니다. zlib 헤더는 기본 수준에서 78 9C이고, 그래서 zlib Base64는 eJ로 시작합니다. 수준 9에서는 78 DA, Base64로 eN입니다.
어떤 호출이 어떤 형식을 만드나
“deflate” 버그 대부분은 양쪽이 같은 단어로 서로 다른 래퍼를 가리키는 데서 생깁니다.
| 언어 | zlib (RFC 1950) | raw deflate (RFC 1951) | gzip |
|---|---|---|---|
| Python | zlib.compress() | zlib.compressobj(wbits=-15) | gzip.compress() |
| Node.js | zlib.deflateSync() | zlib.deflateRawSync() | zlib.gzipSync() |
| 브라우저 | CompressionStream("deflate") | CompressionStream("deflate-raw") | CompressionStream("gzip") |
| PHP | gzcompress() | gzdeflate() | gzencode() |
| Java | new Deflater() | new Deflater(level, true) | GZIPOutputStream |
| .NET | ZLibStream (.NET 6+) | DeflateStream | GZipStream |
| Go | compress/zlib | compress/flate | compress/gzip |
함정에 주의하세요. .NET의 DeflateStream과 Go의 compress/flate는 raw이고, Node와 브라우저의 “deflate"는 zlib입니다. 둘 다 “deflate를 쓰는” C# 서비스와 Node 클라이언트는 한쪽을 고치지 않으면 서로 알아듣지 못합니다.
래퍼별로 쓰이는 곳
- zlib: PDF
FlateDecode스트림, PNG 이미지 데이터, Git 객체, 많은 바이너리 프로토콜과 게임 저장 파일 형식. - raw deflate: SAML HTTP-Redirect 바인딩(SAML 디코더가 처리), ZIP 파일 안의 항목, WebSocket
permessage-deflate. - gzip: 파일, HTTP, 로그. gzip 페이지에서 다룹니다.
코드에서 zlib + Base64
import base64, zlib
packed = base64.b64encode(zlib.compress(b"Hello, world!")).decode()
# 'eJzzSM3JyddRKM8vyklRBAAgXgSK'
text = zlib.decompress(base64.b64decode(packed))
// Node.js: raw deflate for a SAML-style payload
const zlib = require("zlib");
const packed = zlib.deflateRawSync(Buffer.from("Hello, world!")).toString("base64");
// '80jNycnXUSjPL8pJUQQA'
이런 문자열을 다시 읽으려면 세 가지 래퍼를 모두 감지하는 Base64 gzip·zlib 디코더를 쓰세요. 자세한 내용은 Python과 Node.js에 있습니다.
자주 생기는 문제
incorrect header check: zlib 디코더에 raw 또는 gzip 데이터를 넣었습니다. 래퍼를 맞추세요.invalid stored block lengths또는invalid block type: raw deflate 디코더에 zlib 데이터를 넣어 헤더 두 바이트가 deflate 블록으로 읽혔습니다.- 결과가 입력보다 깁니다: 짧은 문자열은 압축되지 않습니다. 대략 50~100바이트 미만이면 일반 Base64가 더 짧습니다.
- 출력이 다른 도구와 바이트 단위로 일치하지 않습니다: 압축 수준과 라이브러리 모두 바이트를 바꾸며, 올바른 압축 해제기라면 어느 쪽에서든 같은 원본을 돌려줍니다.
자주 묻는 질문
zlib과 deflate는 무엇이 다른가요?
Deflate는 압축 알고리즘입니다. raw deflate는 압축된 스트림 그 자체이고, zlib은 그 주위에 2바이트 헤더와 4바이트 Adler-32 체크섬을 더하며, gzip은 10바이트 헤더와 CRC-32가 든 8바이트 트레일러를 더합니다. 가운데의 압축 데이터는 똑같습니다.
'incorrect header check' 오류는 왜 나나요?
압축 해제기가 zlib 헤더를 기대했는데 다른 것, 대개 raw deflate나 gzip을 받았기 때문입니다. 맞는 호출(Python에서 raw deflate라면 zlib.decompress(data, -15))을 쓰거나, 받는 쪽이 기대하는 형식으로 다시 인코딩하세요.
HTTP Content-Encoding: deflate는 raw deflate인가요, zlib인가요?
HTTP 명세는 zlib이라고 정합니다. 일부 오래된 서버가 그 이름으로 raw deflate를 보냈기 때문에, HTTP에서는 gzip이 더 안전한 선택입니다.