Компресирайте BitArray с GZip в C#

Имам BitArray със 100 милиона елемента. Това е около 12,5 милиона. Трябва да компресирам този масив. Използвам GZipStream на Framework.

   public static byte[] Compress(byte[] bytData)
    {
        try
        {
            MemoryStream ms = new MemoryStream();
            Stream s = new GZipStream(ms, CompressionMode.Compress);
            s.Write(bytData, 0, bytData.Length);
            s.Close();
            byte[] compressedData = ms.ToArray();
            return compressedData;
        }
        catch
        {
            return null;
        }
    }

    static void Main(string[] args)
    {
        BitArray t = GetArray();
        byte []byteArray = new byte[100000000/8];
        t.CopyTo(byteArray, 0);
        byte[] compressedData = Compress(byteArray);
        Console.WriteLine(compressedData.Length);
    }
    public static BitArray GetArray()
    {
        Random r = new Random();
        BitArray result = new BitArray(100000000);
        for (int i = 0; i < result.Count; i++)
        {
            if (r.NextDouble() > .5)
            {
                result.Set(i, true);
            }
        }
        return result;
    }
}

Но размерът на променливата compressedData е 12515308. По-голям е от оригиналния масив. Някакви идеи?

Може би имам нужда от друг компресор?


person Leonid    schedule 03.05.2012    source източник
comment
Компресирането работи чрез присвояване на кратки кодове на общи последователности в данните и дълги кодове на редки последователности. Ако данните са напълно произволни, няма много последователности, които се появяват често, така че резултатът може да се окаже по-дълъг от оригинала. Решение: не компресирайте произволни данни. Или ако трябва, просто използвайте PRNG (като Random) и съхранявайте само семената, а не генерираните стойности (процедурно генериране).   -  person dtb    schedule 04.05.2012
comment
Мерси. Трябва да използвам произволни данни. Не мога да използвам GZip. Може и друг компресор. Това не са точно произволни числа, но fop POC използвам произволни. Това е като потребителски код за криптиране. Трябва да е произволно.   -  person Leonid    schedule 04.05.2012
comment
Компресирането след криптиране често е лоша идея (поемате допълнителни разходи за компресиране и ще има минимално, ако има такова, действително намаляване на размера поради причината, спомената от @dtb). Ако е възможно, опитайте да компресирате данните, преди да бъдат криптирани, тогава ще получите най-добри резултати.   -  person carlosfigueira    schedule 04.05.2012


Отговори (2)


Опитахте ли да не използвате произволни данни? Данните, които се компресират добре, не са случайни. Вярвам, че общите алгоритми за компресиране търсят модели от битове, за да компресират. Като прост тест можете да запишете тези произволни байтове във файл и след това да видите какво се случва, когато го компресирате.

person Seth Flowers    schedule 03.05.2012

опитайте да получите грешката, като използвате json_last_error()
person Mark Adler    schedule 03.05.2012
comment
Хехехе как да компресирам 64KB псевдослучайно число в четири байта: [SEED, STREAM_LENGTH]? :) - person JSideris; 14.06.2012