enFGK FGK ºÎÈ£ deFGK FGK ºÎÈ£·ÎºÎÅÍÀÇ º¹È£
FGK ºÎÈ£
long enFGK(unsigned char *code, long clen,
unsigned char *text, long tlen);
FGK ºÎÈ£·ÎºÎÅÍÀÇ º¹È£
long deFGK(unsigned char *text, long tlen,
unsigned char *code, long clen);
FGK ºÎÈ£ ÇÔ¼ö¿¡ ´ëÇØ
code (ÀÔÃâ·Â) FGK ºÎÈ£¸¦ °Ý³³ÇÏ´Â ¹è¿
clen (ÀÔ·Â) ¹è¿ codeÀÇ ±æÀÌ
text (ÀÔ·Â) ÅØ½ºÆ®¸¦ °Ý³³ÇÏ´Â ¹è¿
tlen (ÀÔ·Â) ¹è¿ textÀÇ ±æÀÌ
FGK ºÎÈ£·ÎºÎÅÍÀÇ º¹È£ ÇÔ¼ö¿¡ ´ëÇØ
text (ÀÔÃâ·Â) ÅØ½ºÆ®¸¦ °Ý³³ÇÏ´Â ¹è¿
tlen (ÀÔ·Â) ¹è¿ textÀÇ ±æÀÌ
code (ÀÔ·Â) FGK ºÎÈ£¸¦ °Ý³³ÇÏ´Â ¹è¿
clen (ÀÔ·Â) ¹è¿ codeÀÇ ±æÀÌ
FGK ºÎÈ£ ÇÔ¼ö¿¡ ´ëÇØ
FGK ºÎÈ£ÀÇ ±æÀÌ. encode¿¡ ½ÇÆÐÇßÀ» ¶§´Â -1L.
FGK ºÎÈ£·ÎºÎÅÍÀÇ º¹È£ ÇÔ¼ö¿¡ ´ëÇØ
ÅØ½ºÆ®ÀÇ ±æÀÌ. º¹È£¿¡ ½ÇÆÐÇßÀ» ¶§´Â -1L.
typedef struct {
int chr; /* ¹®ÀÚ */
long count; /* ÀÚ ³ëµåÀÇ ÃâÇö ºóµµÀÇ È */
int parent; /* Ä£³ëµå¿¡ */
int left; /* ÁÂÃøÀÇ ¾ÆÀÌ ³ëµå¿¡ */
int right; /* ¿ìÃøÀÇ ¾ÆÀÌ ³ëµå¿¡ */
} NODE;
#define ROOT 0 /* ·çÆ® */
#define EOF_NODE 1 /* EOF ³ëµå */
#define CHAR_SIZE 256
#define NODE_SIZE (2*CHAR_SIZE+2) /* ³ëµåÀÇ ÃÖ´ë °³¼ö */
long enFGK(unsigned char *code, long clen,
unsigned char *text, long tlen)
{
int i, j, k;
long c, len;
int curChar;
int zeroNode, thisNode, maxid;
int node2id[NODE_SIZE]; /* ³ëµå·ÎºÎÅÍ ±× ³ëµå ¹øÈ£ */
int char2node[CHAR_SIZE];
NODE node[NODE_SIZE]; int freeNode;
char bit[NODE_SIZE]; char *bitp;
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 (tlen <= 0) return -1L;
for (i = 0; i < CHAR_SIZE; i++) char2node[i] = 0;
/* Ãʱâ ÇÏÇÁ¸Ç³ª¹« */
zeroNode = 2;
node[2]. count = 0;
node[2]. parent = ROOT;
node[EOF_NODE]. count = 1;
node[EOF_NODE]. parent = ROOT;
node[ROOT]. count = 0x7FFFFFFFL;
node[ROOT]. parent = 0;
node[ROOT]. left = zeroNode;
node[ROOT]. right = EOF_NODE;
node2id[zeroNode] = 0;
node2id[EOF_NODE] = 1;
node2id[ROOT] = 2;
freeNode = 3;
/* °¢ ¹®ÀÚ¸¦ encode */
for (i = 0, c = 0, len = 0, bitp = bit; ; c++) {
/* ÀÔ·Â ¹®ÀÚ¿¡ ´ëÀÀÇÏ´Â ³ëµå */
if (c >= tlen) thisNode = EOF_NODE;
else if ((thisNode = char2node[curChar = text[c]]) == 0) {
thisNode = zeroNode;
for (j = 7; j >= 0; j--) *bitp++ = curChar & bit1[j];
}
/* ºÎÈ£¾î¸¦ ¾ò´Â´Ù */
k = thisNode;
do {
int parent = node[k]. parent;
*bitp++ = (node[parent]. left == k) ? 0 : 1;
k = parent;
} while (k ! = ROOT);
/* ¿ª¼ø¼¿¡ Ãâ·Â */
do {
if (*--bitp) *code |= bit1[i];
else *code &= bit0[i];
if (++i == 8) {
code++;
if (++len > clen) return -1L;
i = 0;
}
} while (bitp ! = bit);
if (c == tlen) break; /* EOF */
/* ÇÏÇÁ¸Ç³ª¹«¸¦ °»½Å */
while (thisNode ! = ROOT) {
if (thisNode == zeroNode) {
for (j = 0; j < freeNode; j++) node2id[j] += 2;
node[zeroNode]. left = freeNode;
node[freeNode]. count = 0;
node[freeNode]. parent = zeroNode;
node2id[freeNode] = 0;
freeNode++;
node[zeroNode]. right = freeNode;
node[freeNode]. count = 1;
node[freeNode]. parent = zeroNode;
node2id[freeNode] = 1;
char2node[curChar] = freeNode; /* ½Å¹®ÀÚ */
freeNode++;
thisNode = zeroNode;
zeroNode = freeNode - 2;
} else {
if (node[thisNode]. count == 1 &&
node[k = node[thisNode]. parent]. count == 1) {
/* 0-³ëµåÀÇ ÇüÁ¦ */
for (j = 0, maxid = thisNode; j < freeNode; j++)
if (node[j]. count == 1 && j ! = k &&
node2id[j] > node2id[maxid]) maxid = j;
} else {
for (j = 0, maxid = thisNode; j < freeNode; j++)
if (node[thisNode]. count == node[j]. count &&
node2id[j] > node2id[maxid]) maxid = j;
}
if (maxid ! = thisNode) {
int maxidP = node[maxid]. parent;
int thisP = node[thisNode]. parent;
int id = node2id[maxid];
if (node[maxidP]. left == maxid)
node[maxidP]. left = thisNode;
else node[maxidP]. right = thisNode;
if (node[thisP]. left == thisNode)
node[thisP]. left = maxid;
else node[thisP]. right = maxid;
node[maxid]. parent = thisP;
node[thisNode]. parent = maxidP;
node2id[maxid] = node2id[thisNode];
node2id[thisNode] = id;
}
node[thisNode]. count++;
thisNode = node[thisNode]. parent;
}
}
}
if (i > 0) len++;
return (len > clen) ? -1L : len;
}
long deFGK(unsigned char *text, long tlen,
unsigned char *code, long clen)
{
int i, j, k;
long c, len;
int curChar;
int zeroNode, thisNode, maxid;
int node2id[NODE_SIZE]; /* ³ëµå·ÎºÎÅÍ ±× ³ëµå ¹øÈ£ */
NODE node[NODE_SIZE]; int freeNode;
static unsigned char bit1[8] = { 128, 64, 32, 16, 8, 4, 2, 1};
if (clen <= 0) return -1L;
/* Ãʱâ ÇÏÇÁ¸Ç³ª¹« */
zeroNode = 2;
node[2]. chr = CHAR_SIZE+1;
node[2]. count = 0;
node[2]. parent = ROOT;
node[EOF_NODE]. chr = CHAR_SIZE;
node[EOF_NODE]. count = 1;
node[EOF_NODE]. parent = ROOT;
node[ROOT]. count = 0x7FFFFFFFL;
node[ROOT]. parent = 0;
node[ROOT]. left = zeroNode;
node[ROOT]. right = EOF_NODE;
node2id[zeroNode] = 0;
node2id[EOF_NODE] = 1;
node2id[ROOT] = 2;
freeNode = 3;
/* º¹È£È */
for (i = 0, c = 0, len = 0; ; ) {
/* ºÎÈ£¾î¿¡ ´ëÀÀÇÏ´Â ¹®ÀÚ ³ëµå¸¦ ¾ò´Â´Ù */
thisNode = ROOT;
do {
thisNode = (*code & bit1[i]) ?
node[thisNode]. right : node[thisNode]. left;
if (thisNode >= freeNode) return -1L;
if (++i == 8) {
code++;
if (++c > clen) return -1L;
i = 0;
}
} while (node[thisNode]. chr < 0);
if (thisNode == EOF_NODE) break; /* EOF */
if (thisNode == zeroNode) { /* ½Å¹®ÀÚ */
curChar = 0;
for (j = 0; j < 8; j++) {
if (*code & bit1[i]) curChar |= bit1[j];
if (++i == 8) {
code++;
if (++c > clen) return -1L;
i = 0;
}
}
} else curChar = node[thisNode]. chr;
if (++len > tlen) return -1L;
*text++ = curChar; /* ¹®ÀÚÀÇ Ãâ·Â */
/* ÇÏÇÁ¸Ç³ª¹«¸¦ °»½Å */
while (thisNode ! = ROOT) {
if (thisNode == zeroNode) {
for (j = 0; j < freeNode; j++) node2id[j] += 2;
node[zeroNode]. left = freeNode;
node[freeNode]. count = 0;
node[freeNode]. parent = zeroNode;
node2id[freeNode] = 0;
node[freeNode]. chr = CHAR_SIZE + 1;
freeNode++;
node[zeroNode]. right = freeNode;
node[freeNode]. count = 1;
node[freeNode]. parent = zeroNode;
node2id[freeNode] = 1;
node[freeNode]. chr = curChar;
freeNode++;
thisNode = zeroNode;
node[thisNode]. chr = -1;
zeroNode = freeNode - 2;
} else {
if (node[thisNode]. count == 1 &&
node[k = node[thisNode]. parent]. count == 1) {
/* 0-³ëµåÀÇ ÇüÁ¦ */
for (j = 0, maxid = thisNode; j < freeNode; j++)
if (node[j]. count == 1 && j ! = k &&
node2id[j] > node2id[maxid]) maxid = j;
} else {
for (j = 0, maxid = thisNode; j < freeNode; j++)
if (node[thisNode]. count == node[j]. count &&
node2id[j] > node2id[maxid]) maxid = j;
}
if (maxid ! = thisNode) {
int maxidP = node[maxid]. parent;
int thisP = node[thisNode]. parent;
int id = node2id[maxid];
if (node[maxidP]. left == maxid)
node[maxidP]. left = thisNode;
else node[maxidP]. right = thisNode;
if (node[thisP]. left == thisNode)
node[thisP]. left = maxid;
else node[thisP]. right = maxid;
node[maxid]. parent = thisP;
node[thisNode]. parent = maxidP;
node2id[maxid] = node2id[thisNode];
node2id[thisNode] = id;
}
node[thisNode]. count++;
thisNode = node[thisNode]. parent;
}
}
}
return len;
}
ÀÌ·¯ÇÑ ¹®Á¦Á¡À» ÇØ°áÇϱâ À§Çؼ, ÀÔ·Â ÅØ½ºÆ®·ÎºÎÅÍ 1 ¹®ÀÚ¸¦ ÀоîµéÀÏ ¶§ ¸¶´Ù, ±× ½ÃÁ¡±îÁöÀÇ °¢ ¹®ÀÚÀÇ ÃâÇö ºóµµ¸¦ Àç°è»êÇØ, ÇÏÇÁ¸Ç³ª¹«¸¦ ´Ù½Ã ¸¸µé¾î , ¹®ÀÚ¸¦ encode ÇÏ´Â °ÍÀÌ °í¾È µÇ¾ú´Ù. ÇÏÇÁ¸Ç³ª¹«´Â ±× ½ÃÁ¡¿¡¼ÀÇ ÃâÇö ºóµµ¿¡ ´ëÇØ¼ ÃÖÀû (À¸)·Î °è¼Ó µÇµµ·Ï(µíÀÌ) º¯ÈÇϹǷÎ, ÀûÀÀÇü ÇãÇÁ¸¸ ÄÚµùÀ̶ó°í ÇÑ´Ù. ¶Ç ÇÏÇÁ¸Ç³ª¹« ÇÏÁö¸¸ ¹®ÀÚ ¸¶´Ù ¹Ù²î¹Ç·Î, µ¿Àû ÇãÇÁ¸¸ ÄÚµùÀ̶ó°íµµ ÇÑ´Ù.
±×·¯³ª, ½ÇÁ¦·Î ÀÌ¿Í °°ÀÌ ÇØ ÇÏÇÁ¸Ç³ª¹«¸¦ ¹®ÀÚ ¸¶´Ù º¹±¸¼º ÇÏ´Â °ÍÀº, Àϱî ÀÇ °è»ê ½Ã°£ÀÌ °É¸°´Ù. ½ÇÁ¦ÀÇ ÀûÀÀÇü ÇãÇÁ¸¸ ÄÚµù ¾Ë°í¸®Áò¿¡¼´Â, ÇÏÇÁ¸Ç ³ª¹«ÀÇ º¯ÇüÀ» ÃÖ¼ÒÇÑÀ¸·Î Çϱâ À§ÇÑ ±Ã¸®°¡ ÇÊ¿äÇÏ´Ù.
ÀûÀÀÇü ÇãÇÁ¸¸ ÄÚµùÀ» ÀûÀº °è»ê·®À¸·Î ½ÇÇöµÇ´Â ¾ÆÀ̵ð¾î´Â, ÃÖÃÊ 1970 ³â´ë¿¡ N. Faller ¿Í R. G. Gallager ¿¡ ÀÇÇØ µ¶¸³¿¡ °í¾È µÇ¾ú´Ù. 1985³â¿¡ Knuth °¡ ÀÌ ¾ÆÀ̵ð¾î·Î °³·®À» ´õÇØ FGK ¾Ë°í¸®ÁòÀ» °³¹ßÇß´Ù.
¾Ë°í¸®ÁòÀÇ ±âÃÊ´Â, Gallager ¿¡ ÀÇÇØ Á¤ÀÇµÈ ÇüÁ¦ Á¶°ÇÀÌ´Ù. ÀÖ´Ù ³ª¹«°¡ ÇüÁ¦ Á¶°ÇÀ» ä¿î´Ù´Â °ÍÀº, ·çÆ® ÀÌ¿ÜÀÇ °¢ ³ëµå°¡ 1°³ÀÇ ÇüÁ¦µµ , °Ô´Ù°¡, ³ëµå¸¦ ÇüÁ¦³¢¸®°¡ ¼·Î ÀÌ¿ôÀÌ µÇµµ·Ï(µíÀÌ) Áß·®°¨ÀÇ ºñÁõ°¡¼ø¼¿¡ ´Ã¾î³õ´Â °Í ÇÏÁö¸¸ ÇÒ ¼ö ÀÖ´Â °æ¿ì¸¦ ¸»ÇÑ´Ù. Gallager ´Â, ¾î´À ³ª¹«°¡ ÇÏÇÁ¸Ç³ª¹«ÀÎ °ÍÀº, ±× ³ª¹«°¡ ÇüÁ¦ Á¶°ÇÀ» ä¿ì´Â °æ¿ìÀ̸ç, ÇÑÆí ±× °æ¿ì¿¡ ÇÑÁ¤ÇÏ´Â °ÍÀ» ³ªÅ¸³Â´Ù. ¿©±â¼ ¸»ÇÑ´Ù Áß·®°¨°ú´Â ³ëµåÀÇ ¹®ÀÚ ÃâÇö ºóµµÀÇ °ÍÀ¸·Î, ³»ºÎ ³ëµåÀÇ ¹®ÀÚ ÃâÇö ºóµµ´Â ±× ¾ÆÀÌ ³ëµåÀÇ ±×°ÍÀÇ ÈÀÌ´Ù.
FGK ºÎÈ£¿¡ ´ëÇØµµ, Ãʱâ ÇÏÇÁ¸Ç³ª¹«´Â ·çÆ®¿Í ±× ¾ÆÀÌ ³ëµå 2ÀÍ°í µÈ´Ù. 2»ìÀÇ ¾ÆÀÌ ³ëµå´Â, °¢°¢ ¡¸¹ÌÃâÇö ¹®ÀÚ(ÀÌÇÏ 0-³ëµå¶ó°í ºÎ¸¥´Ù)¡¹¶ó°í EOF (ºÎÈ£ÀÇ Á¾·á¸¦ ³ªÅ¸³»´Â Ưº° ±âÈ£)¿¡ ´ëÀÀÇÑ´Ù. 0-³ëµåÀÇ ÃâÇö ºóµµ¸¦ 0, EOF ³ëµåÀÇ ÃâÇö ºóµµ¸¦ 1 À¸·Î ÇÑ´Ù. ¶Ç, ³ëµå ¹øÈ£´Â 0-³ëµå°¡ 0, EOF ³ëµå ÇÏÁö¸¸ 1, ·çÆ®°¡ 2 ÀÇ ¼ø¼·Î ÇÑ´Ù.
0-³ëµå´Â, ÇöÀç±îÁö ÃâÇöÇϰí ÀÖÁö ¾Ê´Â ¹®ÀÚ°¡ óÀ½À¸·Î ÀÔ·Â ÅØ½ºÆ®Áß¿¡ ³ªÅ¸³µ´Ù ¶§¿¡, ±× ¹®ÀÚ¸¦ encode Çϱâ À§Çؼ »ç¿ëÇÑ´Ù. ±× °æ¿ì,0-³ëµå¿¡ ´ëÇÑ ºÎÈ£ ¸»À» Ãâ·ÂÇÑ ÈÄ¿¡, ¹®ÀÚ ±× ÀÚüµµ Ãâ·ÂÇÑ´Ù(¿¹¸¦ µé¾î ASCII ÄÚµåµî¿¡ ÀÇÇÑ´Ù).
ÇÏÇÁ¸Ç³ª¹«¸¦ ÀÌÇÏ¿Í °°ÀÌ °»½ÅÇÑ´Ù.