C # (534 znaków)
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);}}}
Znacznie bardziej czytelny:
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);
}
}
}
Komentarze:
Oczekuje ścieżki do pliku jako pierwszego argumentu wiersza polecenia.
Plik wyjściowy to plik wejściowy + .gz
.
Nie używam żadnych bibliotek do gzip, deflate lub CRC32. Wszystko tam jest.
Ten „kompresor” zwiększa rozmiar pliku sześciokrotnie. Ale jest w prawidłowym formacie gzip!
Testowane przy użyciu GNU gunzip i WinRAR.