»ê¼ú ºÎÈ£


ÇÔ¼ö¸í
enArith  »ê¼ú ºÎÈ£
deArith  »ê¼ú ºÎÈ£·ÎºÎÅÍÀÇ º¹È£
Çü½Ä
»ê¼ú ºÎÈ£
    long enArith(unsigned char *code, long clen,
                 unsigned char *text, long tlen);

»ê¼ú ºÎÈ£·ÎºÎÅÍÀÇ º¹È£
    long deArith(unsigned char *text, long tlen,
                 unsigned char *code, long clen);
Àμö
»ê¼ú ºÎÈ£ ÇÔ¼ö¿¡ ´ëÇØ
    code  (ÀÔÃâ·Â) »ê¼ú ºÎÈ£¸¦ °Ý³³ÇÏ´Â ¹è¿­
    clen  (ÀÔ·Â) ¹è¿­ codeÀÇ ±æÀÌ
    text  (ÀÔ·Â) ÅؽºÆ®¸¦ °Ý³³ÇÏ´Â ¹è¿­
    tlen  (ÀÔ·Â) ¹è¿­ textÀÇ ±æÀÌ

»ê¼ú ºÎÈ£·ÎºÎÅÍÀÇ º¹È£ ÇÔ¼ö¿¡ ´ëÇØ
    text  (ÀÔÃâ·Â) ÅؽºÆ®¸¦ °Ý³³ÇÏ´Â ¹è¿­
    tlen  (ÀÔ·Â) ¹è¿­ textÀÇ ±æÀÌ
    code  (ÀÔ·Â) »ê¼ú ºÎÈ£¸¦ °Ý³³ÇÏ´Â ¹è¿­
    clen  (ÀÔ·Â) ¹è¿­ codeÀÇ ±æÀÌ
ÇÔ¼öÄ¡
»ê¼ú ºÎÈ£ ÇÔ¼ö¿¡ ´ëÇØ
    »ê¼ú ºÎÈ£ÀÇ ±æÀÌ. encode¿¡ ½ÇÆÐÇßÀ» ¶§´Â -1L.

»ê¼ú ºÎÈ£·ÎºÎÅÍÀÇ º¹È£ ÇÔ¼ö¿¡ ´ëÇØ
    ÅؽºÆ®ÀÇ ±æÀÌ. º¹È£¿¡ ½ÇÆÐÇßÀ» ¶§´Â -1L.
ÁÖÀÇ »çÇ×

¿ë·Ê(arithmetic-test.c )

ÇÁ·Î±×·¥(arithmetic.c )
#define CHAR_SIZE    256      /* ¹®ÀÚ Á¾·ù */

#define Q      0xffffffffL
#define Q1     0x40000000L
#define Q2     0x80000000L
#define Q3     0xC0000000L

long enArith(unsigned char *code, long clen, unsigned char *text, long tlen){

int i, k; long c, len; int comp; long max; long sum, t; long count[CHAR_SIZE+2]; unsigned long L, R, q, r; long outbit(); if (tlen <= 0 || clen <= 2*CHAR_SIZE)
return -1L; /* °¢ ¹®ÀÚÀÇ ÃâÇö ºóµµ¸¦ °è»ê */ for (i = 0; i < CHAR_SIZE; i++)
count[i] = 0; for (c = 0; c < tlen; c++)
count[text[c]]++; /* ÃÖ´ë ÃâÇö ºóµµÀÇ °ªÀÌ 2¹ÙÀÌÆ®¸¦ ³ÑÁö ¾Ê°Ô Á¶Á¤ÇÑ´Ù */ for (i = 0, max = 0; i < CHAR_SIZE; i++) if (count[i] > max) max = count[i]; if ((k = max/0x10000L) > 0) for (i = 0, k++; i < CHAR_SIZE; i++) if (count[i] > 0) { count[i] /= k; if (count[i] == 0)
count[i] = 1; } /* °¢ ¹®ÀÚÀÇ ÃâÇö ºóµµ¸¦ Ãâ·Â */ for (i = 0, len = 0; i < CHAR_SIZE; i++) { code[len++] = (count[i] >> 8) & 0xff; code[len++] = count[i] & 0xff; } /* EOF */ count[CHAR_SIZE] = 1; /* ´©Àû ºóµµ·Î °íÄ£´Ù */ t = count[0]; count[0] = 0; for (i = 1; i <= CHAR_SIZE+1; i++) { long tmp = count[i]; count[i] = count[i-1] + t; t = tmp; } sum = count[CHAR_SIZE+1]; /* °¢ ¹®ÀÚ¸¦ encode */ L = 0; R = Q; for (c = 0, comp = 0, i = 0; ; c++) { k = (c == tlen) ? CHAR_SIZE : text[c]; /* ±¸°£À» °»½Å */ q = (R - L) / sum; r = (R - L) % sum; R = L + q*count[k+1] + (r*count[k+1]) /sum - 1; L = L + q*count[k] + (r*count[k]) /sum + 1; /* ºñÆ®¸¦ Ãâ·Â */ while (R - L <= Q1) { if (R < Q2) { len = outbit(0, code, len, comp, &i); if (len > clen) return -1L; comp = 0; } else if (L >= Q2) { len = outbit(1, code, len, comp, &i); if (len > clen) return -1L; comp = 0; L -= Q2; R -= Q2; } else if (Q1 <= L && R < Q3) { comp++; L -= Q1; R -= Q1; } L <<= 1; R <<= 1; } if (k == CHAR_SIZE) break; } if (L <= Q1) { len = outbit(0, code, len, comp, &i); len = outbit(1, code, len, 0, &i); } else if (L <= Q2) { len = outbit(1, code, len, comp, &i); len = outbit(0, code, len, 0, &i); } else { len = outbit(1, code, len, comp, &i); len = outbit(1, code, len, 0, &i); } if (i > 0) { while (i > 0) outbit(0, code, len, 0, &i); len++; } return (len > clen) ? -1L : len; } static long outbit(int bit, unsigned char *code, long len, int comp, int *i) { static unsigned char bit0[8] = {~128,~64,~32,~16,~8,~4,~2,~1}; static unsigned char bit1[8] = { 128, 64, 32, 16, 8, 4, 2, 1}; if (bit) code[len] |= bit1[*i]; else code[len] &= bit0[*i]; if (++(*i) == 8) { len++; *i = 0; } while (comp--) { if (bit) code[len] &= bit0[*i]; else code[len] |= bit1[*i]; if (++(*i) == 8) { len++; *i = 0; } } return len; } long deArith(unsigned char *text, long tlen, unsigned char *code, long clen) { unsigned char c; int i, k; long j, len; long sum, t; long count[CHAR_SIZE+2]; unsigned long L, R, V, q, r; static unsigned char bit1[8] = {128,64,32,16,8,4,2,1}; if (clen <= 2*CHAR_SIZE) return -1L; /* °¢ ¹®ÀÚÀÇ ÃâÇö ºóµµ¸¦ ¼¼Æ® */ for (i = 0; i < CHAR_SIZE; i++) count[i] = 0; for (i = 0; i < CHAR_SIZE; i++) { count[i] = *code++; count[i] = (count[i] << 8) | *code++; } /* EOF */ count[CHAR_SIZE] = 1; /* ´©Àû ºóµµ·Î °íÄ£´Ù */ t = count[0]; count[0] = 0; for (i = 1; i <= CHAR_SIZE+1; i++) { long tmp = count[i]; count[i] = count[i-1] + t; t = tmp; } sum = count[CHAR_SIZE+1]; /* º¹È£È­ */ L = 0; R = Q; V = 0; for (i = 0, j = 2*CHAR_SIZE; i < 4; i++) { V <<= 8; if (j++ < clen) V |= *code++; } c = (j <= clen) ? *code : 0; for (i = 0, len = 0; ; ) { /* ±¸°£À» °»½Å */ q = (R - L) / sum; r = (R - L) % sum; for (k = 0; k <= CHAR_SIZE; k++) { R = L + q*count[k+1] + (r*count[k+1]) /sum; if (R > 0 && --R >= V) break; } L = L + q*count[k] + (r*count[k]) /sum + 1; if (k == CHAR_SIZE) break; *text++ = k; if (++len > clen) return -1L; /* ±¸°£ÀÇ ½¬ÇÁÆ® */ while (R - L <= Q1) { if (R < Q2) ; else if (L >= Q2) { L -= Q2; R -= Q2; V -= Q2; } else if (Q1 <= L && R < Q3) { L -= Q1; R -= Q1; V -= Q1; } L <<= 1; R <<= 1; V <<= 1; if (c & bit1[i]) V |= 1; if (++i == 8) { c = (j++ <= clen) ? *++code : 0; i = 0; } } } return len; }
¼³¸í
1960³â´ë¿¡ P. Elias ¿¡ ÀÇÇØ °í¾È µÈ ºÎÈ£°¡, ±âÈ£(¹®ÀÚ) ¿­Àüü (À»)¸¦ 1°³ÀÇ ºÎÈ£¾î·Î Çؼ­ , encode³ª º¹È£È­¿¡ »ê¼ú ¿¬»ê(»çÄ¢ ¿¬»ê)¿¡ (ÀÌ)¶ó°í ½ÇÇàµÇ´Â °ÍÀ¸·ÎºÎÅÍ »ê¼ú ºÎÈ£¿Í ÃÑĪµÇ°í ÀÖ´Ù.

»ê¼ú ºÎÈ£´Â Æø³Ð°Ô ¿¬±¸°¡ ÀÌ·ç¾îÁö°Ô µÈ °ÍÀº 1970³â´ëÀÇ ÈĹÝÀ̸ç, ÀϹÝÀûÀ¸·Î´Â ±×´ÙÁö ¾Ë·ÁÁöÁö ¾ÊÀº °ÍÀÌ Çö»óÀÌ´Ù.

»ê¼ú ºÎÈ£´Â À̷лó, Æò±Õ ºÎÈ£ÀåÀÌ ¿£Æ®·ÎÇÇ°¡ µÈ´Ù. Áï, Æò±Õ ºÎÈ£Àå¿¡ °ü°èÇؼ­´Â, »ê¼ú ºÎÈ£´Â ÃÖÀû ºÎÈ£ÀÌ´Ù. ÀÌ°Í¿¡ ´ëÇؼ­, Àß ¾Ë·ÁÁ® ÀÖ´Ù ÇãÇÁ¸¸ ÄÚµùÀº ±× Æò±Õ ºÎÈ£ÀåÀº ¹Ýµå½Ã ¿£Æ®·ÎÇÇ°¡ µÇÁö ¾Ê´Â´Ù. ±×·¯³ª »ê¼ú ºÎÈ£¿¡ ´ëÇؼ­´Â, encode¶§, ¹«ÇÑÀÚ¸®¼öÀÇ ½Ç¼ö ¿¬»êÀÌ À̷лó ÇÊ¿äÇϹǷÎ, ½Ç¿ë »óÀ¯ÇÑÇüÀÇ Á¤¼ö·Î ±Ù»ç ÇÏ´Â ±Ã¸®°¡ ÇÊ¿ä ÀÏ °ÍÀÌ´Ù.

»ê¼ú ºÎÈ£´Â ÀÔ·Â ±âÈ£(¹®ÀÚ)ÀÇ ÃâÇö È®·ü¿¡ ±Ù°ÅÇØ ´ÜÀ§ ±¸°£ [0, 1)(Á´ÜÀÌ 0 (À»)¸¦ Æ÷ÇÔÇØ, ¿ì´ÜÀÌ 1À» Æ÷ÇÔÇÏÁö ¾Ê´Â ±¸°£)À» ¼ø¼­´ë·Î Ãà¼ÒÇØ, ÃÖÁ¾ÀûÀ¸·Î ¾òÀ» ¼ö ÀÖ´ø ±¸°£³»ÀÇ °ªÀ» ºÎÈ£·Î ÇÏ´Â ºÎÈ£ÀÌ´Ù. ÇãÇÁ¸¸ ÄÚµù¿¡¼­´Â ÃâÇö È®·üÀÇ Å« ±âÈ£¿¡ ª´Ù ºÎÈ£¾î¸¦ ÇÒ´çÇϴµ¥ ´ëÇØ, »ê¼ú ºÎÈ£¿¡¼­´Â, ÃâÇö È®·üÀÇ Å« ¹®ÀÚ¿¡ ÆøÀÇ Å« ±¸°£À» ¹èºÐÇÑ´Ù.

°ü·Ã ÇÔ¼ö
¼¨³Í¡¤ÆÄ³ë ºÎÈ£, ÇãÇÁ¸¸ ÄÚµù, FGK ºÎÈ£, LZ77 ºÎÈ£, LZW ºÎÈ£