เขียนไฟล์บีบอัดสำหรับไฟล์ gzip


11

ภารกิจของการท้าทายนี้มีดังต่อไปนี้:

เขียนโปรแกรมที่อ่านไฟล์ขนาดที่เหมาะสม (สมมติว่า <16 MB) จาก stdin หรือที่อื่น (แต่คุณต้องการ แต่ต้องไม่ฮาร์ดโค้ด) และใส่เอาท์พุทที่ถูกบีบอัดไปยัง stdout เอาต์พุตจะต้องเป็นไฟล์บีบอัด gzip ที่ถูกต้องและหากไฟล์บีบอัดวิ่งผ่าน gunzip ก็ควรให้ไฟล์เดียวกันทุกประการ

กฎระเบียบ

  • ภาษาโปรแกรมที่ใช้ต้องเป็นที่รู้จักก่อนการแข่งขันนี้จะเริ่มขึ้น
  • คะแนนของโปรแกรมของคุณคือจำนวนตัวอักษรของซอร์สโค้ดหรือโปรแกรมที่ประกอบ (สิ่งที่สั้นกว่า)
  • คุณไม่ได้รับอนุญาตให้ใช้ไลบรารีการบีบอัดใด ๆ ที่มีอยู่
  • มีความสุข!

2
อนุญาตให้ใช้ไลบรารีที่มีอยู่แล้วหรือไม่
hallvabo

@hallvabo: ไม่ ลืมสิ่งนี้ ขอบคุณ
FUZxxl

2
วิธีที่ดีที่สุดในการทำเช่นนี้อาจเป็นเพียงการใส่แผ่นข้อมูลด้วยเครื่องหมาย "บล็อกต่อไปนี้ไม่บีบอัด" ที่จุดเริ่มต้นของทุกบล็อก
อานนท์

gzip เป็นภาษาโปรแกรม ไม่ใช่ทัวริงที่สมบูรณ์แม้ว่า
Alexandru

1
นี้เหมือนกันสวยมากกับปืนและปราดปัญหา ทำไมไม่มีใครโพสต์คำตอบของพวกเขาที่นี่มากกว่าที่ codegolf.com อยู่นอกเหนือฉันเว้นแต่พวกเขาต้องการที่จะแก้ปัญหาในภาษาที่ไม่ได้รับการสนับสนุนจาก codegolf.com (เช่น GolfScript)
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 มันคือทั้งหมดที่อยู่ในนั้น

  • “ compressor” นี้จะเพิ่มขนาดไฟล์ขึ้นเป็น 6 เท่า แต่มันอยู่ในรูปแบบ gzip ที่ถูกต้อง!

  • ทดสอบโดยใช้ GNU gunzip และ WinRAR

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.