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 ÄÚµåµî¿¡ ÀÇÇÑ´Ù).
ÇÏÇÁ¸Ç³ª¹«¸¦ ÀÌÇÏ¿Í °°ÀÌ °»½ÅÇÑ´Ù.