Tại sao tệp 7zipped lớn hơn tệp thô? [bản sao]


37

Có thể trùng lặp:
Tại sao ZIP nén không nén bất cứ thứ gì?

Tôi đã thử 7zipping một tập tin .exe nhưng nó thực sự trở nên lớn hơn.

nhập mô tả hình ảnh ở đây

Đây có phải là kết quả mong đợi?


3
Vâng, đó là kết quả mong đợi. Tại sao? Bởi vì khi một cái gì đó đã được nén (= sử dụng không gian nhỏ hơn có thể), nó không thể được nén thêm.
woliveirajr

4
Chỉ cần thêm vào những người khác - vì tệp exe này cụ thể là một trình cài đặt, hầu hết nội dung của nó có thể là một kho lưu trữ zip hoặc cab. Bạn sẽ không nhận được kết quả tương tự từ một tệp exe bình thường (nhưng hầu hết các tệp exe bình thường sẽ không phải là 145 megabyte)
Random832

1
Giải thích chỉ sử dụng logic cơ bản: Nén tìm thấy cho một tệp thô một tệp nén UNIQUE và cho tệp nén tệp UNIQUE thô (không nén) tệp gốc. Hãy tưởng tượng bạn có các tệp 8 bit và muốn nén chúng thành các tệp 5 bit. Có 256 tệp 8 bit duy nhất, nhưng chỉ có 32 tệp 5 bit duy nhất (!) Vì vậy, một số tệp 8 bit phải được nén vào cùng một tệp 5 bit (!). Và nếu 2 tệp thô khác nhau được nén vào cùng một tệp ZIP, bạn muốn lấy tệp nào sau khi giải nén? Đối với bất kỳ phương pháp nén nào, nếu tồn tại các tệp trở nên nhỏ hơn sau khi nén, thì phải tồn tại các tệp đó, trở nên lớn hơn (!)
Ivan Kuckir

Câu trả lời:


78

Nó đi xuống một khái niệm gọi là entropy . Xem Wikipedia .

Ý tưởng cơ bản là, nếu tồn tại một hoạt động nén luôn có thể làm cho một tệp nhỏ hơn, thì logic ra lệnh rằng hoạt động nén sẽ có thể giảm bất kỳ tệp nào xuống 0 byte và vẫn giữ lại tất cả dữ liệu. Nhưng điều này là vô lý , bởi vì chúng tôi biết rằng 0 byte không thể truyền tải bất kỳ thông tin nào cả. Vì vậy, chúng tôi đã chứng minh rằng không thể tồn tại thuật toán nén luôn làm cho đầu vào của nó nhỏ hơn, bởi vì nếu đó là trường hợp, mọi thông tin có thể được lưu trữ trong 0 byte - nhưng 0 byte ngụ ý không có thông tin, vì vậy bạn có thể ' t đồng thời không có thông tin và tất cả thông tin. Do đó, nó là vô lý.

Do khái niệm lý thuyết này, mọi chương trình nén bạn từng sử dụng sẽ tăng kích thước (hoặc tốt nhất, duy trì cùng kích thước) một số đầu vào. Đó là, đối với bất kỳ thuật toán nén nào bạn thiết kế hoặc sử dụng, sẽ có một số đầu vào nhất định sẽ nhỏ hơn và một số thuật toán sẽ không.

Dữ liệu đã nén nói chung là một ứng cử viên khủng khiếp để nén thêm, bởi vì hầu hết các thuật toán nén không mất dữ liệu đều dựa trên cùng các nguyên tắc lý thuyết. Đó khả năng nén dữ liệu kém nén hơn nữa; nhưng điều này kém hiệu quả hơn là chỉ đơn giản là nén nó bằng thuật toán có sẵn tốt nhất từ ​​dữ liệu gốc để bắt đầu.

Ví dụ: nếu bạn có tệp văn bản 100 MB và nén nó bằng thuật toán Zip thông thường, nó có thể bị nén xuống còn 50 MB. Nếu sau đó bạn nén tệp Zip bằng LZMA2, bạn có thể giảm xuống còn 40 hoặc 45 MB, vì LZMA có tỷ lệ nén cao hơn đối với hầu hết dữ liệu có thể nén hơn so với Zip. Vì vậy, lý do là nó cũng có thể nén dữ liệu Zip, vì Zip không hoàn toàn hút toàn bộ entropy ra khỏi nó. Nhưng nếu bạn loại bỏ hoàn toàn bộ chứa Zip, bạn có thể có được nó thậm chí còn nhỏ hơn bằng cách nén văn bản thô bằng LZMA2, có khả năng mang lại thứ gì đó theo thứ tự 30 - 35 MB (đây chỉ là "số không khí" để minh họa khái niệm) .

Trong trường hợp nhị phân mà bạn đang cố nén, nó lớn hơn vì định dạng tệp 7-Zip phải tạo cấu trúc bên trong của riêng nó và đóng gói dữ liệu của tệp thực thi đã nén thành định dạng 7-Zip. Điều này chứa những thứ như từ điển, tiêu đề tệp, v.v. Những dữ liệu bổ sung này thường được bù đắp nhiều hơn nhờ tiết kiệm nén dữ liệu, nhưng có vẻ như tệp thực thi mà bạn đang cố nén đã được nén bằng một số dạng LZMA; nếu không, nó có thể sẽ thu nhỏ kích thước của tệp thực thi hoặc tăng rất nhẹ, thay vì tăng thêm 2 MB (rất nhiều).


btw phần quan trọng nhất để trả lời câu hỏi này nằm ở cuối: "Phần này chứa những thứ như từ điển, tiêu đề tệp, v.v. Những dữ liệu bổ sung này thường được bù đắp nhiều hơn nhờ tiết kiệm nén dữ liệu, nhưng nó có vẻ như tệp thực thi mà bạn đang cố nén đã được nén bằng một số dạng LZMA "
jhocking

6
@jhocking: Không, phần quan trọng nhất nằm ở giữa: "Mỗi chương trình nén bạn từng sử dụng sẽ tăng kích thước của ... một số đầu vào." Định dạng tệp của 7zip có từ điển / tiêu đề tệp / vv, nhưng ngay cả khi 7zip sử dụng thuật toán không có bất kỳ thứ gì trong số đó, chúng tôi vẫn đảm bảo rằng một số đầu vào (trên thực tế, hầu hết) sẽ có đầu ra as-lớn-hoặc-lớn hơn bản thân đầu vào. Đây là một thực tế cơ bản của lý thuyết thông tin và không liên quan gì đến tiêu đề tệp.
BlueRaja - Daniel Pflughoeft

2
@Mehrdad Chắc chắn: Chỉ cần viết một thuật toán "nén" luôn trả về đầu vào ban đầu. Ở đó; làm xong. : P ... Bên cạnh đó, không - bất kỳ thuật toán nén nào là thuật toán hoàn toàn sẽ có một số siêu dữ liệu, ngay cả khi nó chỉ là một bit khi bắt đầu tệp cho biết liệu tệp có được nén hay không (0 == không nén, 1 == nén). Nếu bạn sẽ sửa đổi nội dung của tệp TẠI TẤT CẢ , bạn cần một số siêu dữ liệu. Và nếu bạn đang sửa đổi nội dung, bạn sẽ làm cho một số đầu vào lớn hơn.
allquixotic

1
Tuy nhiên, nếu câu hỏi của bạn là "Có thuật toán nén nào không làm tăng độ dài của đầu vào vượt quá một lượng siêu dữ liệu cố định không", thì câu trả lời là: Tôi không biết, nhưng về mặt lý thuyết thì có thể thực hiện được. Dễ dàng, trong thực tế. Tất cả những gì bạn phải làm là phát triển một định dạng chứa có thể chứa tệp gốc hoặc luồng dữ liệu nén. Sau đó, khi bạn tạo tệp lưu trữ, hãy thử nén: nếu kích thước nén lớn hơn đầu vào, chỉ cần lưu trữ đầu vào ban đầu và đóng gói siêu dữ liệu của bạn ở phía trước. Kích thước tệp sẽ tăng, nhưng nếu siêu dữ liệu nhỏ (tiếp)
allquixotic

2
@Mehrdad: "Có thuật toán nén nào (tuy nhiên kém) không làm tăng độ dài của bất kỳ đầu vào nào không? " - Câu trả lời là không. Có những 2^(n+1)-1thông điệp có thể có kích thước n-bit trở xuống. Thuật toán của chúng tôi phải ánh xạ mỗi một trong số này thành một đầu ra duy nhất . Nếu thậm chí một trong số này được ánh xạ tới một giá trị có ít bit hơn, thì một giá trị khác nhất thiết phải được ánh xạ tới một giá trị có nhiều hơn.
BlueRaja - Daniel Pflughoeft

7

Các thuật toán nén cơ bản được sử dụng trong 7z là lossless . Điều đó có nghĩa là bạn có thể lặp lại nén-giải nén một tệp nhiều lần. Hơn nữa, sau mỗi lần lặp, tệp sẽ giữ nguyên chính xác .

Thật không may, bạn không thể mong đợi một thuật toán nén lossless được áp dụng nhiều lần mà luôn có kết quả dương. Có một ranh giới nghiêm ngặt mà nó không thể nhảy qua. Roughly, ranh giới này phụ thuộc vào mức độ chặt chẽ của một chuỗi đầu vào tập hợp dữ liệu ngẫu nhiên. Trên tất cả, các thuật toán lossless được sử dụng để nén tệp, truyền dữ liệu Internet HTML, sao lưu và các hoạt động khác mong muốn tệp đầu ra được giải nén thành chính xác cùng một tệp đầu vào.

Ngược lại với nén không mất dữ liệu , bạn luôn có thể mong đợi giảm kích thước tệp sau khi nén với các thuật toán nén mất (hoặc mất) . Mặt trái là bạn không thể khôi phục chính xác một tệp gốc sau một lần lặp giải nén nén. Các thuật toán này nổi tiếng nhất đối với việc truyền và lưu trữ âm thanh / video / hình ảnh.

bzip2 , LZMA , LZMA2 và các thuật toán khác được sử dụng bởi định dạng 7z đều không mất dữ liệu . Do đó, sẽ có một giới hạn mà sau đó nó không thể nén được nữa. Trên hết, hình ảnh thực thi (.exe) thường là các tệp được nén cao. 7zip như nhiều công cụ nén khác nhúng một số siêu dữ liệu, trong thực tế có thể làm cho tệp đầu ra lớn hơn.

Teaser não: điều gì xảy ra nếu chúng ta có một thuật toán lossless luôn có thể giảm kích thước tệp?

Trong trường hợp này, bạn sẽ luôn thấy rằng tệp nén nhỏ hơn tệp đầu vào. Xem một bình luận dưới đây tại sao nó không thể.


5
Chứng minh bằng sự mâu thuẫn. Giả thuyết: Giả sử luôn có thể nén một tệp với thuật toán lossless. Bước 1. Nén đơn làm cho một tệp đầu ra nhỏ hơn ít nhất một bit. Nếu vậy, sau một số lần lặp, chúng ta sẽ kết thúc với một tệp chỉ có hai bit. Bước 2 Lặp lại tiếp theo làm cho một tệp có kích thước 1 bit. Bước 3 Nhưng các thuật toán nén là lossless, có nghĩa là chỉ có một giải nén hợp lệ được phép. Rõ ràng bạn không thể khôi phục 2 bit gốc từ 1 bit nén - bạn sẽ phải đoán. Điểm cuối cùng vi phạm giả thuyết.
oleksii

Bạn không thể đảm bảo thuật toán làm cho tệp nhỏ hơn nhưng bạn có thể đảm bảo thuật toán sẽ không tăng kích thước bằng cách không áp dụng "nén" trong những trường hợp đó. Để thực sự không tăng kích thước tệp, bạn sẽ phải chỉ ra điều này ngoài băng (ví dụ như trong tên tệp).
jeteon

@jeteon Tôi không chắc bạn đang nói gì.
oleksii

Tôi chỉ nói thêm rằng vì bạn luôn có tùy chọn không nén đầu vào, nên bạn có thể có một chương trình nén không nén tệp ở mức tồi tệ nhất. Về cơ bản, nếu bạn xác định rằng phiên bản nén lớn hơn phiên bản không nén, thì bạn chỉ cần bỏ nó. Sau đó, bạn cũng sẽ phải chỉ ra bằng cách nào đó rằng đây là trường hợp mà không cần thêm kích thước của đầu ra để bộ giải nén biết tệp không được nén. Cách duy nhất để làm điều này mà không làm tăng kích thước tệp, là làm một cái gì đó như thay đổi tên tệp.
jeteon

@jeteon ơi, tôi hiểu rồi. Đúng, có ý nghĩa.
oleksii

6

Nếu tệp thực thi ban đầu đã được nén (hoặc chứa dữ liệu được nén nhiều hoặc dữ liệu không nén được) thì nén nó sẽ tăng kích thước.


2

Hầu hết các thuật toán nén sử dụng cái được gọi là bảng ký hiệu, về cơ bản chỉ là các phần của tệp mà nó sử dụng làm phần tử mà nó CÓ THỂ nén. Điều này, tất nhiên, tạo ra một số chi phí trong tệp nhưng thường dẫn đến một tệp nhỏ hơn nhiều.

Trong các tệp đã được nén, nó vẫn tạo ra một tập hợp các ký hiệu, nhưng có rất ít có thể giảm kích thước trên. Trong trường hợp của bạn, bảng biểu tượng của tệp đã được nén có thể nằm trong vùng lân cận 2 MB hoặc có thể nhiều hơn nếu nó đã quản lý để thực hiện một số thao tác nén.


0

ideea nén:

phần mềm nén tạo danh sách các tệp và loại bỏ nội dung trùng lặp.

khi nén các tệp đã nén, bạn có thể nhận được các tệp nén của mình lớn hơn tệp gốc.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.