LZ77 ºÎÈ£


ÇÔ¼ö¸í
enLZ77  LZ77 ºÎÈ£
deLZ77  LZ77 ºÎÈ£·ÎºÎÅÍÀÇ º¹È£
Çü½Ä
LZ77 ºÎÈ£
    long enLZ77(unsigned char *code, long clen,
                unsigned char *text, long tlen);

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

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

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

¿ë·Ê(lz77-test.c )

ÇÁ·Î±×·¥(lz77.c )
#define F       128           /* ÃÖÀå ÀÏÄ¡ ij¸¯ÅÍ ¶óÀÎÀÇ ±æÀÌÀÇ »óÇÑ */
#define LOG2F   7             /* 2^7 = 128 */
#define N0      4096
#define LOG2N   12            /* 2^12 = 4096 */

#define N       (N0+F)        /* ½½¶óÀ̵åâÀÇ Å©±â */

long enLZ77(unsigned char *code, long clen,
            unsigned char *text, long tlen)
{
    int      i, j;
    int      w, l, x;
    int      ww, ll;
    long     len;
    unsigned char *wintop, *winbrk;
    unsigned char *texttop, *textend;
    unsigned char prewin[N0];
    static int bit0[12] =
           {~1,~2,~4,~8,~16,~32,~64,~128,~256,~512,~1024,~2048};
    static int bit1[12] =
           { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048};

    for (i = 0; i < N0; i++) prewin[i] = 0;

    wintop = prewin; winbrk = wintop + N0;
    texttop = text;  textend = text + tlen;
    for (i = 7, len = 0; ; ) {
        unsigned char *wp;

        if (texttop >= textend) break;

        /* ÃÖÀå ÀÏÄ¡ ij¸¯ÅÍ ¶óÀÎÀ» ã¾Æ³½´Ù */
        w = l = 0;
        for (wp = wintop, ww = 0; ww < N0; ww++) {
            if (wp == winbrk) wp = text;
            if (*wp++ == *texttop) {
                unsigned char *p, *q;

                for (p = wp, q = texttop+1, ll = 1; ll < F; ll++) {
                    if (p == winbrk) p = text;
                    if (q == textend || *p++ ! = *q++) {
                        if (ll >= l) {
                            w = ww;
                            l = ll;
                        }
                        break;
                    }
                }
            }
        }
        x = *(texttop + l);

        /* ÃÖÀå ÀÏÄ¡ ij¸¯ÅÍ ¶óÀÎÀÇ °³½Ã À§Ä¡¸¦ Ãâ·Â */
        for (j = LOG2N-1; j >= 0; j--) {
            if (w & bit1[j]) *code |= bit1[i];
            else             *code &= bit0[i];
            if (i-- == 0) {
                code++;
                if (++len > clen) return -1L;
                i = 7;
            }
        }

        /* ÃÖÀå ÀÏÄ¡ ij¸¯ÅÍ ¶óÀÎÀÇ ±æÀ̸¦ Ãâ·Â */
        for (j = LOG2F-1; j >= 0; j--) {
            if (l & bit1[j]) *code |= bit1[i];
            else             *code &= bit0[i];
            if (i-- == 0) {
                code++;
                if (++len > clen) return -1L;
                i = 7;
            }
        }

        /* ÃÖÀå ÀÏÄ¡ ij¸¯ÅÍ ¶óÀÎÀÇ ´ÙÀ½ÀÇ ¹®ÀÚ¸¦ Ãâ·Â */
        for (j = 7; j >= 0; j--) {
            if (x & bit1[j]) *code |= bit1[i];
            else             *code &= bit0[i];
            if (i-- == 0) {
                code++;
                if (++len > clen) return -1L;
                i = 7;
            }
        }

        /* ½½¶óÀ̵åâÀ» µÚ·Î ºñÄÑ ³õ´Â´Ù */
        texttop += ++l;
        if (wintop + l >= winbrk) wintop = text + (l - (winbrk-wintop));
        else wintop += l;
    }
    if (i < 7) len++;
    return (len > clen) ?  -1L : len;
}

long deLZ77(unsigned char *text, long tlen,
            unsigned char *code, long clen)
{
    int      i, j;
    int      w, l, x;
    unsigned char *wintop, *winbrk, *texttop;
    unsigned char prewin[N0];
    long     c, len;
    static int bit1[12] =
           { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048};

    if (clen <= 0) return -1;

    for (i = 0; i < N0; i++) prewin[i] = 0;
    wintop = prewin; winbrk = wintop + N0;
    texttop = text;

    for (i = 7, len = 0, c = 1; ; ) {
        unsigned char *wp;

        w = l = x = 0;
        /* ÃÖÀå ÀÏÄ¡ ij¸¯ÅÍ ¶óÀÎÀÇ °³½Ã À§Ä¡ */
        for (j = LOG2N-1; j >= 0; j--) {
            if (*code & bit1[i]) w |= bit1[j];
            if (i-- == 0) {
                code++;
                if (++c > clen) return -1L;
                i = 7;
            }
        }
        /* ÃÖÀå ÀÏÄ¡ ij¸¯ÅÍ ¶óÀÎÀÇ ±æÀÌ */
        for (j = LOG2F-1; j >= 0; j--) {
            if (*code & bit1[i]) l |= bit1[j];
            if (i-- == 0) {
                code++;
                if (++c > clen) return -1L;
                i = 7;
            }
        }
        /* ÃÖÀå ÀÏÄ¡ ij¸¯ÅÍ ¶óÀÎÀÇ ´ÙÀ½ÀÇ ¹®ÀÚ */
        for (j = 7; j >= 0; j--) {
            if (*code & bit1[i]) x |= bit1[j];
            if (i-- == 0) {
                code++;
                ++c;
                i = 7;
            }
        }

        /* ij¸¯ÅÍ ¶óÀÎÀ» º¹È£ ÇÑ´Ù */
        if ((wp = wintop + w) >= winbrk) wp = texttop + (w - (winbrk-wintop));
        for (j = l; j > 0; j--) {
            if (wp == winbrk) wp = texttop;
            *text++ = *wp++;
        }

        len += l++;
        
        if (c >= clen) break;

        /* ½½¶óÀ̵åâÀ» µÚ·Î ºñÄÑ ³õ´Â´Ù */
        *text++ = x;
        if (wintop + l >= winbrk) wintop = texttop + (l - (winbrk-wintop));
        else wintop += l;

        len++;
    }
    return len;
}
¼³¸í
LZ77 ºÎÈ£´Â J. Ziv ¿Í A. Lempel °¡ 1977³â °í¾È µÈ, »õ·Î¿î ¹ß»ó¿¡ ±âÃʸ¦ µÎ´Â ºÎÈ£ÀÌ´Ù. ºÎÈ£ ÇÏ·Á°í Çϴ ij¸¯ÅÍ ¶óÀÎÀÌ ÀüÀÇ ÅؽºÆ®¿¡ Á¸ÀçÇÏ°í ÀÖ¾ú´Ù (ÀÌ)¶ó¸é, Àü¿¡ ÀÖ´Â °°Àº ij¸¯ÅÍ ¶óÀÎÀÇ À§Ä¡¿Í ±æÀ̸¦ ºÎÈ£¾î·Î¼­ »ç¿ëÇÑ´Ù. °°Àº ij¸¯ÅÍ ¶óÀÎ ÇÏÁö¸¸ ÅؽºÆ®¿¡ ¹Ýº¹ÇØ ³ªÅ¸³µÀ» °æ¿ì¿¡, Å« ¾ÐÃà È¿°ú¸¦ ¾òÀ» ¼ö ÀÖ´Ù.

LZ77 ºÎÈ£¿¡¼­´Â, ÇöÀç ºÎÈ£¸¦ ½Ç½ÃÇÏ°í ÀÖ´Â ¹®ÀÚ¸¦ Æ÷ÇÔÇÑ Ä³¸¯ÅÍ ¶óÀÎÀ» ½½¶óÀ̵åâÀ̶ó°í ºÒ·¯, ±× Áß¿¡ Àִ ij¸¯ÅÍ ¶óÀÎÀÌ ÂüÁ¶ÀÇ ´ë»óÀÌ µÈ´Ù. ¶Ç, ºÎÈ£¾î´Â, m, l, x ·ÎºÎÅÍ µÈ´Ù 2 Áø¼ö·Î ³ªÅ¸³½´Ù.

m: ½½¶óÀ̵åâ¿¡ ÀÖ´Â ÃÖÀå ÀÏÄ¡ ij¸¯ÅÍ ¶óÀÎÀÇ À§Ä¡
l: ½½¶óÀ̵åâ¿¡ ÀÖ´Â ÃÖÀå ÀÏÄ¡ ij¸¯ÅÍ ¶óÀÎÀÇ ±æÀÌ
x: ÃÖÀå ÀÏÄ¡ ij¸¯ÅÍ ¶óÀÎÀÇ ´ÙÀ½ÀÇ ¹®ÀÚ

ij¸¯ÅÍ ¶óÀÎÀÌ ½½¶óÀ̵åâ¿¡ Á¸ÀçÇÏÁö ¾Ê¾Ò´ø °æ¿ì´Â m = 0, l = 0 À¸·Î ÇÑ´Ù. ¶Ç, ½º ³îÀÌ ±â±¸Ã¢ÀÌ ºÎÈ£¾î¸¦ Ãâ·ÂÇÒ ¶§¸¶´Ù, l+1 ¹®ÀںР´ÙÀ½ÀÇ Ä³¸¯ÅÍ ¶óÀο¡ ºñÄÑ ³õ´Â´Ù.

ÀÌ¿Í °°ÀÌ, ÃÖÀå ÀÏÄ¡ ij¸¯ÅÍ ¶óÀÎÀ» °ú°ÅÀÇ ÅؽºÆ®·ÎºÎÅÍ Ã£¾Æ³»°í(»çÀüÀÇ ÂüÁ¶¶ó°íµµ ¸»ÇÑ´Ù), ±× °³½Ã À§Ä¡¿Í ±æÀ̸¦ ºÎÈ£¾î·Î¼­ »ç¿ëÇÏ´Â °ÍÀÌ, LZ77 ºÎÈ£ÀÇ Æ¯Â¡ÀÌ´Ù. °³½Ã À§Ä¡¿Í ±æÀÌ¿¡ °üÇÑ Ç¥ÇöÀÇ ¹æ¹ýÀ̳ª ÃÖÀå ÀÏÄ¡ ij¸¯ÅÍ ¶óÀÎÀÇ Å½»öÀÇ ¹æ¹ý¿¡ µû¶ó, ¸î°³ÀÇ ¹Ù¸®¿¡À̼ÇÀÌ Á¸ÀçÇÏ°í ÀÖ´Ù.

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