Z85를 인코딩하고 디코딩하는 방법
- 입력 · Hex에 바이트를 hex로 붙여넣으세요. 공백, 콜론,
0x접두사를 받아들이므로 hex 덤프를 그대로 붙여넣어도 됩니다. - 출력 · Z85 (ZeroMQ) 에서 Z85를 확인하세요.
- 바이트 수가 4의 배수가 아니면 그 개수를 알려 주는 오류가 납니다. 양쪽이 그 확장에 합의했을 때만 불완전한 마지막 블록 허용 (비표준) 을 켜세요.
- 디코딩하려면 방향 토글에서 Z85 (ZeroMQ) → Hex를 누르고 Z85 문자열을 붙여넣으세요. 다른 형태로 보려면 변환 후를 Base64나 텍스트로 설정하고, 바이너리 파일은 바이트 저장으로 받으세요.
명세의 테스트 벡터
ZeroMQ의 Z85 명세(ZeroMQ RFC 시리즈의 RFC 32)는 테스트 값 두 개를 제시합니다. 이 도구는 둘 다 그대로 재현합니다.
| Hex | Z85 |
|---|---|
86 4F D2 6F B5 59 F7 5B | HelloWorld |
8E 0B DD 69 76 28 B9 1D 8F 24 55 87 EE 95 C5 B0 4D 48 96 3F 79 25 98 77 B4 9C D9 06 3A EA D3 B7 | JTKVSB%%)wK0E.X)V>+}o?pNmC{O&4W4b!Ni{Lh6 |
첫 번째는 블록 구조를 보여 줍니다. 8바이트, 블록 두 개, 열 글자입니다. 두 번째는 32바이트 키와 그 40자 인코딩으로, CurveZMQ 설정에서 보는 크기입니다.
몇 가지 경계 값: 0 바이트 4개는 00000, ff 바이트 4개는 %nSc0입니다. Z85에는 0 블록 단축 표기가 없으므로 0이 이어져도 블록마다 다섯 글자입니다.
ZeroMQ가 Z85를 쓰는 이유
CurveZMQ 키는 랜덤 32바이트입니다. ZeroMQ에는 이것을 설정 파일, 명령줄, 소스 코드에 일반 문자열로 넣을 방법이 필요했고, Z85는 그 목적으로 설계되었습니다.
- 원시 바이트보다 25% 커서 Base64의 33%보다 작으므로, 32바이트 키가 44자가 아니라 40자입니다.
- 알파벳에
",',\, 백틱이 없어 키를 C, Python, 셸의 문자열 리터럴에 이스케이프 없이 넣을 수 있습니다.,와;도 피합니다. - 숫자와 영문자가 먼저 오고(
0-9 a-z A-Z), 그 뒤에 문장 부호 23개.-:+=^!/*?&<>()[]{}@%$#가 옵니다.
<, >, &는 여전히 들어 있으므로 XML이나 HTML 안의 Z85는 이스케이프가 필요합니다. JSON에서는 필요 없습니다.
Python에서 Z85
Z85와 Python의 b85encode는 계산 방식이 같고 알파벳만 다르므로, 문자 치환으로 서로 바꿀 수 있습니다.
import base64
B85 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~"
Z85 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-:+=^!/*?&<>()[]{}@%$#"
TO_Z85 = str.maketrans(B85, Z85)
FROM_Z85 = str.maketrans(Z85, B85)
def z85encode(data: bytes) -> str:
if len(data) % 4:
raise ValueError("Z85 needs a multiple of 4 bytes")
return base64.b85encode(data).decode().translate(TO_Z85)
def z85decode(text: str) -> bytes:
return base64.b85decode(text.translate(FROM_Z85))
z85encode(bytes.fromhex("864FD26FB559F75B")) # 'HelloWorld'
이미 PyZMQ를 쓰고 있다면 zmq.utils.z85.encode와 decode가 같은 일을 합니다. C에서는 libzmq에 zmq_z85_encode와 zmq_z85_decode가 있습니다. Python의 바이트 처리는 Python 페이지에서 더 다룹니다.
자주 생기는 문제
- “Z85는 4바이트 블록을 인코딩하는데 데이터는 N바이트입니다”. 입력이 블록 단위로 맞지 않습니다. 키 전체를 복사했는지 확인하세요. 32바이트 키가 31바이트로 나온다면 hex 두 자리를 잃은 것입니다.
- “Z85는 5자 단위 그룹이 필요한데 N자가 남습니다”. Z85 문자열이 잘렸거나 문자가 더 붙었습니다. CurveZMQ 키는 정확히 40자여야 합니다.
- 문자열은 디코딩되는데 키가 동작하지 않습니다. Ascii85나 Git Base85일 수 있습니다. 길이 규칙은 같지만 알파벳이 달라서 같은 문자가 다른 바이트로 디코딩됩니다. Base85 페이지에서 변환 전을 다른 변형으로 설정해 시도해 보세요.
자주 묻는 질문
Z85는 왜 4바이트의 배수를 요구하나요?
명세가 Z85를 온전한 4바이트 블록에 대해서만 정의하므로, 디코더는 5문자마다 4바이트라고 믿을 수 있습니다. 다른 길이의 데이터는 애플리케이션이 패딩하거나 프레이밍해야 합니다. 그래도 끝부분을 Ascii85 방식으로 인코딩하려면 불완전한 마지막 블록 허용 (비표준) 을 켜세요.
Z85 CurveZMQ 키는 몇 자인가요?
40자입니다. CurveZMQ 공개 키와 비밀 키는 32바이트이고, 32 / 4 × 5 = 40입니다. zmq_curve_keypair()가 반환하는 길이이며, C에서는 끝에 널 문자가 하나 더 붙습니다.
Z85는 Ascii85와 같은 것인가요?
계산 방식은 같고 알파벳이 다릅니다. 둘 다 4바이트를 85진수 다섯 자리로 쓰지만, Z85는 숫자와 영문자를 앞에 두고 따옴표와 백슬래시를 피하며, z 단축 표기나 <~ ~> 구분자가 없습니다.
Python에서 Z85를 인코딩하려면 어떻게 하나요?
표준 라이브러리에는 Z85가 없지만 base64.b85encode가 같은 계산을 하므로, 출력 알파벳만 바꾸면 Z85가 됩니다. 이 페이지의 코드가 그렇게 합니다. PyZMQ에도 zmq.utils.z85가 들어 있습니다.