Есть ли способ узнать, был ли байт [] сжат gzipstream?

Есть ли способ узнать, был ли байт [] сжат (или нет) GzipStream.net класс?

РЕДАКТИРОВАТЬ: просто хочу знать, сжат ли массив byte[] (так как я всегда буду использовать GzipStream для сжатия и распаковки)

4 ответа

GZipStream - это DeflateStream с дополнительным заголовком и трейлером.

Формат указан в RFC 1952.


Класс.NET 4.0 GZipStream записывает в качестве заголовка следующие байты:

byte[] headerBytes = new byte[] { 0x1f, 0x8b, 8, 0, 0, 0, 0, 0, 4, 0 };
if (compressionLevel == 10)
{
    headerBytes[8] = 2;
}

Трейлер состоит из контрольной суммы CRC32 и длины несжатых данных.

Благодаря объяснениям @dtd, это работает для меня: (@stackruuser, вы можете этого захотеть?)

public static class CompressionHelper
{
    public static byte[] GZipHeaderBytes = {0x1f, 0x8b, 8, 0, 0, 0, 0, 0, 4, 0};
    public static byte[] GZipLevel10HeaderBytes = {0x1f, 0x8b, 8, 0, 0, 0, 0, 0, 2, 0};

    public static bool IsPossiblyGZippedBytes(this byte[] a)
    {
        var yes = a.Length > 10;

        if (!yes)
        {
            return false;
        }

        var header = a.SubArray(0, 10);

        return header.SequenceEqual(GZipHeaderBytes) || header.SequenceEqual(GZipLevel10HeaderBytes);
    }
}

Вы можете посмотреть на первые несколько байтов магического заголовка, чтобы увидеть, является ли он сжатым, но если компрессор.net не записывает дополнительную информацию в одно из комментариев или других необязательных полей, вы, вероятно, не можете сказать, кто был компрессором.

http://www.onicos.com/staff/iz/formats/gzip.html

Вы также можете посмотреть на поле типа ОС, чтобы увидеть, было ли это FAT или NTFS, но это еще не говорит о том, что оно было написано на C#...

Ответы, опубликованные выше, в большинстве случаев выполняют эту работу, но имейте в виду, что последний байт в заголовке обозначает идентификатор операционной системы. Это означает, что этот код может работать локально, но может не работать при развертывании в Azure. В моем случае этот последний байт был не 0, как в примере, а 0xA (10).

См. также https://en.wikipedia.org/wiki/Gzip для небольшого объяснения заголовка.

Другие вопросы по тегам