도구스개발

비대칭 수 체계(rANS) 부호화 계산기

상태를 큰 정수 하나로 들고 다니며 기호를 그 안에 밀어 넣는 엔트로피 부호화 rANS의 인코딩·디코딩을 단계별로 보여 줍니다. 기호를 넣은 순서와 꺼내는 순서가 정반대(LIFO)라는 것을 실제 수치로 확인합니다.

쉼표나 공백으로 구분합니다.

전체 빈도 합 M8
"a"빈도 5 · 누적 [0, 5)
"b"빈도 2 · 누적 [5, 7)
"c"빈도 1 · 누적 [7, 8)
기호당 평균 엔트로피 하한1.2988 bit

인코딩 후 최종 상태

660

x0=1 · 기호 7개 · log₂(최종/x0) ≈ 9.37 bit

인코딩 — 넣은 순서 그대로

기호x (전)x′ (후)
a11
b16
a69
a912
c12103
b103414
a414660

왕복 검산 (뒤집으면 원래와 같은가)

일치

디코딩 후 x0 복원: 1 (원래 1)

디코딩 — 꺼내는 순서(넣은 순서의 정반대, LIFO)

x (전)slot기호x (후)
6604a414
4146b103
1037c12
124a9
91a6
66b1
11a1

꺼낸 기호를 순서대로 이으면 "a b c a a b a"로, 넣은 순서("a b a a c b a")를 정확히 거꾸로 한 것입니다.

기호를 넣은 순서와 꺼내는 순서가 정반대입니다(LIFO). 인코딩은 기호를 s₁, s₂, ..., sₙ 순서로 상태 하나에 계속 밀어 넣고, 디코딩은 맨 나중에 넣은 sₙ부터 꺼내 맨 마지막에 s₁이 나옵니다. 스택에 쌓았다가 뽑는 것과 같은 구조입니다.
실전 rANS는 상태가 너무 커지지 않도록 비트를 쏟아내며 좁히는 정규화를 겹쳐 씁니다. 이 계산기는 핵심 재귀식만 보여주려고 정규화를 생략했고, 그래서 상태가 계속 커질 수 있어 BigInt로 계산합니다.

사용 방법

  1. 1기호와 빈도를 정해 누적빈도표를 만듭니다.
  2. 2부호화할 기호 열과 시작 상태 x0을 입력합니다.
  3. 3상태가 기호마다 어떻게 불어나는지 단계별로 봅니다.
  4. 4디코딩이 정반대 순서로 기호를 꺼내는지, 원래 순서로 뒤집으면 같은지 확인합니다.

자주 묻는 질문

기호마다 빈도 f_s, 전체 빈도의 합 M, 그 기호 앞의 누적빈도 c_s를 정해 두고, x′ = ⌊x/f_s⌋·M + (x mod f_s) + c_s로 계산합니다. 빈도가 큰(자주 나오는) 기호일수록 ⌊x/f_s⌋가 작아 상태가 덜 불어나므로, 자주 나오는 기호는 싼 값에, 드문 기호는 비싼 값에 상태를 불리는 셈입니다.

인코딩은 기호를 s₁, s₂, ..., sₙ 순서로 상태 하나에 계속 밀어 넣습니다. 디코딩은 그 최종 상태에서 시작해 맨 나중에 넣은 sₙ부터 꺼내고 맨 마지막에 s₁이 나옵니다. 스택에 쌓았다가 뽑는 것과 같은 후입선출(LIFO) 구조이기 때문이며, 그래서 원래 순서로 복원하려면 디코딩된 목록을 다시 뒤집어야 합니다.

slot = x′ mod M을 구해, 그 값이 어느 기호의 누적빈도 구간 [c_s, c_s+f_s)에 들어가는지 찾으면 그것이 방금 넣은 기호입니다. 이전 상태는 x = f_s·⌊x′/M⌋ + slot − c_s로 되돌립니다. 인코딩 식을 정확히 거꾸로 푼 것입니다.

허프만은 기호마다 정수 개의 비트만 쓸 수 있어 확률이 정확히 2의 거듭제곱 분의 1이 아니면 손해를 봅니다. 산술부호화는 로그 비트(분수 비트)를 쓸 수 있어 그 손해가 없지만 구현이 복잡하고 느립니다. rANS는 산술부호화만큼 분수 비트를 쓰면서도 정수 연산 몇 번으로 끝나 훨씬 단순하고 빠릅니다 — Zstandard·LZFSE가 이것을 쓰는 이유입니다.

실전 구현은 상태가 너무 커지지 않도록 비트를 쏟아내며 상태를 좁히는 정규화(renormalization)를 겹쳐 씁니다. 이 계산기는 이해를 돕기 위해 정규화를 생략하고 상태가 임의 정밀도 정수(BigInt)로 자유롭게 자라도록 두어, 핵심 재귀식만 그대로 보여 줍니다.

전송되지 않습니다. 계산은 모두 브라우저 안에서 이뤄지고 입력값은 이 기기에만 남습니다.

알아두면 좋은 점

  • 기호를 인코딩한 뒤 디코딩해 순서를 뒤집으면 원래 기호 열과 정확히 같은지, 무작위(결정적) 긴 수열을 포함해 확인했습니다.
  • 디코딩을 원래 길이만큼 끝까지 하면 시작 상태 x0로 정확히 되돌아오는지 여러 x0에서 검산했습니다.
  • 빈도가 큰 기호일수록 같은 시작 상태에서 상태가 덜 불어나는지, 균등분포에서 엔트로피 하한이 log₂(알파벳 크기)와 같은지 확인했습니다.
  • 정규화를 생략했기 때문에 긴 기호 열을 인코딩하면 상태가 매우 큰 정수가 됩니다. 이 계산기는 BigInt로 계산하므로 자바스크립트 숫자의 안전정수 한계에 걸리지 않습니다.

함께 보면 좋은 도구

마지막 검증: 2026년 9월 2일 · 결과는 참고용 추정치입니다.