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.
#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;
}
»ê¼ú ºÎÈ£´Â Æø³Ð°Ô ¿¬±¸°¡ ÀÌ·ç¾îÁö°Ô µÈ °ÍÀº 1970³â´ëÀÇ ÈĹÝÀ̸ç, ÀϹÝÀûÀ¸·Î´Â ±×´ÙÁö ¾Ë·ÁÁöÁö ¾ÊÀº °ÍÀÌ Çö»óÀÌ´Ù.
»ê¼ú ºÎÈ£´Â À̷лó, Æò±Õ ºÎÈ£ÀåÀÌ ¿£Æ®·ÎÇǰ¡ µÈ´Ù. Áï, Æò±Õ ºÎÈ£Àå¿¡ °ü°èÇØ¼´Â, »ê¼ú ºÎÈ£´Â ÃÖÀû ºÎÈ£ÀÌ´Ù. À̰Ϳ¡ ´ëÇØ¼, Àß ¾Ë·ÁÁ® ÀÖ´Ù ÇãÇÁ¸¸ ÄÚµùÀº ±× Æò±Õ ºÎÈ£ÀåÀº ¹Ýµå½Ã ¿£Æ®·ÎÇǰ¡ µÇÁö ¾Ê´Â´Ù. ±×·¯³ª »ê¼ú ºÎÈ£¿¡ ´ëÇØ¼´Â, encode¶§, ¹«ÇÑÀÚ¸®¼öÀÇ ½Ç¼ö ¿¬»êÀÌ À̷лó ÇÊ¿äÇϹǷÎ, ½Ç¿ë »óÀ¯ÇÑÇüÀÇ Á¤¼ö·Î ±Ù»ç ÇÏ´Â ±Ã¸®°¡ ÇÊ¿ä ÀÏ °ÍÀÌ´Ù.
»ê¼ú ºÎÈ£´Â ÀÔ·Â ±âÈ£(¹®ÀÚ)ÀÇ ÃâÇö È®·ü¿¡ ±Ù°ÅÇØ ´ÜÀ§ ±¸°£ [0, 1)(Á´ÜÀÌ 0 (À»)¸¦ Æ÷ÇÔÇØ, ¿ì´ÜÀÌ 1À» Æ÷ÇÔÇÏÁö ¾Ê´Â ±¸°£)À» ¼ø¼´ë·Î Ãà¼ÒÇØ, ÃÖÁ¾ÀûÀ¸·Î ¾òÀ» ¼ö ÀÖ´ø ±¸°£³»ÀÇ °ªÀ» ºÎÈ£·Î ÇÏ´Â ºÎÈ£ÀÌ´Ù. ÇãÇÁ¸¸ ÄÚµù¿¡¼´Â ÃâÇö È®·üÀÇ Å« ±âÈ£¿¡ ª´Ù ºÎÈ£¾î¸¦ ÇÒ´çÇϴµ¥ ´ëÇØ, »ê¼ú ºÎÈ£¿¡¼´Â, ÃâÇö È®·üÀÇ Å« ¹®ÀÚ¿¡ ÆøÀÇ Å« ±¸°£À» ¹èºÐÇÑ´Ù.