分析压缩文件或任何存档文件

时间:2013-06-06 14:51:13

标签: methods compression zip

我想知道是否有人可以推荐一种工具来分析压缩文件或任何存档文件。我不是要检查存档中的内容,而是更多关于它是如何压缩的,使用什么压缩方法等。

谢谢!

2 个答案:

答案 0 :(得分:3)

对于压缩成ZIP文件的数据,命令行工具 zipinfo 非常有用,特别是在使用'-v'参数时(对于详细模式)。我从这个zip-related question on SuperUser

中了解到了zipinfo

答案 1 :(得分:0)

我最近遇到了一个问题,一个工具创建的zip文件只能在某些程序中打开,而不能在其他程序中打开。问题是目录在zip文件中没有条目,只是目录中存在文件而暗示它们。同样,所有目录分隔符都是反斜杠,而不是正斜杠。

zipinfo并没有真正帮助这些位。我需要查看zip条目,因此我最终将其写成以下内容,从而使我可以区分具有已知良好版本的目录条目

using System;
using System.IO;
using System.Text;

namespace ZipAnalysis
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.WriteLine("No filename specified");
                Console.WriteLine("Press any key to exit");
                Console.ReadKey(true);
                return;
            }
            string fileName = args[0];
            if (!File.Exists(fileName))
            {
                Console.WriteLine($"File not found: {fileName}");
                Console.WriteLine("Press any key to exit");
                Console.ReadKey(true);
                return;
            }

            using (var file = File.OpenRead(fileName))
            {
                //First, find the End of central directory record

                BinaryReader reader = new BinaryReader(file);
                int entryCount = ReadEndOfCentralDirectory(reader);
                if (entryCount > 0)
                {
                    ReadCentralDirectory(reader, entryCount);
                }
            }
            Console.WriteLine("Press any key to exit");
            Console.ReadKey(true);
        }

        private static int ReadEndOfCentralDirectory(BinaryReader reader)
        {
            var b = reader.ReadByte();
            int result = 0;
            while (result == 0 && reader.BaseStream.Position < reader.BaseStream.Length)
            {
                while (b != 0x50)
                {
                    if (reader.BaseStream.Position < reader.BaseStream.Length)
                        b = reader.ReadByte();
                    else
                        break;
                }

                if (reader.BaseStream.Position >= reader.BaseStream.Length)
                {
                    break;
                }

                if (reader.ReadByte() == 0x4b && reader.ReadByte() == 0x05 && reader.ReadByte() == 0x06)
                {
                    int diskNumber = reader.ReadInt16();
                    int centralDirectoryStartDiskNumber = reader.ReadInt16();
                    int centralDirectoryCount = reader.ReadInt16();
                    int centralDirectoryTotal = reader.ReadInt16();
                    result = centralDirectoryTotal;
                    int centralDirectorySize = reader.ReadInt32();
                    int centralDirectoryOffset = reader.ReadInt32();
                    int commentLength = reader.ReadInt16();
                    string comment = Encoding.ASCII.GetString(reader.ReadBytes(commentLength));
                    Console.WriteLine("EOCD Found");
                    Console.WriteLine($"Disk Number: {diskNumber}");
                    Console.WriteLine($"Central Directory Disk Number: {centralDirectoryStartDiskNumber}");
                    Console.WriteLine($"Central Directory Count: {centralDirectoryCount}");
                    Console.WriteLine($"Central Directory Total: {centralDirectoryTotal}");
                    Console.WriteLine($"Central Directory Size: {centralDirectorySize}");
                    Console.WriteLine($"Central Directory Offset: {centralDirectoryOffset}");
                    Console.WriteLine($"Comment: {comment}");
                    reader.BaseStream.Seek(centralDirectoryOffset, SeekOrigin.Begin);
                }
            }
            return result;
        }

        private static void ReadCentralDirectory(BinaryReader reader, int count)
        {
            for (int i = 0; i < count; i++)
            {
                var signature = reader.ReadInt32();
                if (signature == 0x02014b50)
                {
                    Console.WriteLine($"Version Made By: {reader.ReadInt16()}");
                    Console.WriteLine($"Minimum version to extract: {reader.ReadInt16()}");
                    Console.WriteLine($"Bit Flag: {reader.ReadInt16()}");
                    Console.WriteLine($"Compression Method: {reader.ReadInt16()}");
                    Console.WriteLine($"File Last Modification Time: {reader.ReadInt16()}");
                    Console.WriteLine($"File Last Modification Date: {reader.ReadInt16()}");
                    Console.WriteLine($"CRC: {reader.ReadInt32()}");
                    Console.WriteLine($"CompressedSize: {reader.ReadInt32()}");
                    Console.WriteLine($"UncompressedSize: {reader.ReadInt32()}");
                    var fileNameLength = reader.ReadInt16();
                    var extraFieldLength = reader.ReadInt16();
                    var fileCommentLength = reader.ReadInt16();
                    Console.WriteLine($"Disk number where file starts: {reader.ReadInt16()}");
                    Console.WriteLine($"Internal file attributes: {reader.ReadInt16()}");
                    Console.WriteLine($"External file attributes: {reader.ReadInt32()}");
                    Console.WriteLine($"Relative offset of local file header: {reader.ReadInt32()}");
                    string filename = Encoding.ASCII.GetString(reader.ReadBytes(fileNameLength));
                    string extraField = Encoding.ASCII.GetString(reader.ReadBytes(extraFieldLength));
                    string fileComment = Encoding.ASCII.GetString(reader.ReadBytes(fileCommentLength));
                    Console.WriteLine($"Filename: {filename}");
                    Console.WriteLine($"Extra Field: {extraField}");
                    Console.WriteLine($"File Comment: {fileComment}");
                }
            }
        }
    }
}