gzip 파일을위한 압축 유틸리티 작성


11

이 과제의 과제는 다음과 같습니다.

stdin 또는 다른 곳에서 (그러나 원하는대로 하드 코딩해서는 안 됨) 적당한 크기의 파일 (<16MB라고 함)을 읽는 프로그램을 작성하고 압축 된 출력을 stdout에 넣습니다. 출력은 유효한 gzip 압축 파일이어야하며 압축 파일이 gunzip을 통해 실행되는 경우 이전과 정확히 동일한 파일을 생성해야합니다.

규칙

  • 이 경쟁이 시작 되기 전에 사용 된 프로그래밍 언어를 알아야합니다
  • 프로그램 점수는 소스 코드 또는 조립 된 프로그램의 문자 수입니다 (더 짧은 것)
  • 기존 압축 라이브러리를 사용할 수 없습니다.
  • 즐기세요!

2
내장 라이브러리를 사용할 수 있습니까?
hallvabo

@hallvabo : 아뇨. 이것을 잊었다. Thx
FUZxxl

2
이 작업을 수행하는 가장 좋은 방법은 모든 블록의 시작 부분에 "다음 블록은 압축되지 않은"마커로 입력을 채우는 것입니다.
아논.

gzip은 프로그래밍 언어입니다. 튜링이 완성하지는 못했습니다.
Alexandru

1
이것은 Guns and Zips 문제 거의 동일합니다 . codegolf.com에서 지원하지 않는 언어 (예 : GolfScript)로 답변을 해결하지 않는 한 누구나 왜 codegolf.com이 아닌 여기에 답변을 게시 할 수 있습니까?
Chris Jester-Young

답변:


10

C # (534 자)

using System.IO;using B=System.Byte;class X{static void Main(string[]a){var f=File.ReadAllBytes(a[0]);int l=f.Length,i=0,j;var p=new uint[256];for(uint k=0,r=0;k<256;r=++k){for(j=0;j<8;j++)r=r>>1^(r&1)*0xedb88320;p[k]=r;}uint c=~(uint)0,n=c;using(var o=File.Open(a[0]+".gz",FileMode.Create)){o.Write(new B[]{31,139,8,0,0,0,0,0,4,11},0,10);for(;i<l;i++){o.Write(new B[]{(B)(i<l-1?0:1),1,0,254,255,f[i]},0,6);c=p[(c^f[i])&0xFF]^c>>8;}c^=n;o.Write(new[]{(B)c,(B)(c>>8),(B)(c>>16),(B)(c>>24),(B)l,(B)(l>>8),(B)(l>>16),(B)(l>>24)},0,8);}}}

훨씬 더 읽기 쉬운 :

using System.IO;
using B = System.Byte;
class X
{
    static void Main(string[] a)
    {
        // Read file contents
        var f = File.ReadAllBytes(a[0]);
        int l = f.Length, i = 0, j;

        // Initialise table for CRC hashsum
        var p = new uint[256];
        for (uint k = 0, r = 0; k < 256; r = ++k)
        {
            for (j = 0; j < 8; j++)
                r = r >> 1 ^ (r & 1) * 0xedb88320;
            p[k] = r;
        }

        uint c = ~(uint) 0, n = c;

        // Write the output file
        using (var o = File.Open(a[0] + ".gz", FileMode.Create))
        {
            // gzip header
            o.Write(new B[] { 31, 139, 8, 0, 0, 0, 0, 0, 4, 11 }, 0, 10);
            for (; i < l; i++)
            {
                // deflate block header plus one byte of payload
                o.Write(new B[] { (B) (i < l - 1 ? 0 : 1), 1, 0, 254, 255, f[i] }, 0, 6);
                // Compute CRC checksum
                c = p[(c ^ f[i]) & 0xFF] ^ c >> 8;
            }
            c ^= n;
            o.Write(new[] {
                // CRC checksum
                (B) c, (B) (c >> 8), (B) (c >> 16), (B) (c >> 24),
                // original file size
                (B) l, (B) (l >> 8), (B) (l >> 16), (B) (l >> 24)
            }, 0, 8);
        }
    }
}

코멘트:

  • 첫 번째 명령 줄 인수로 파일 경로를 예상합니다.

  • 출력 파일은 입력 파일 + .gz입니다.

  • gzip, deflate 또는 CRC32를 수행하는 데 라이브러리를 사용하지 않습니다. 모두 거기에 있습니다.

  • 이 "압축기"는 파일 크기를 6 배 증가시킵니다. 그러나 유효한 gzip 형식입니다!

  • GNU gunzip 및 WinRAR을 사용하여 테스트했습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.