TVE.PureArchive
1.0.0
dotnet add package TVE.PureArchive --version 1.0.0
NuGet\Install-Package TVE.PureArchive -Version 1.0.0
<PackageReference Include="TVE.PureArchive" Version="1.0.0" />
<PackageVersion Include="TVE.PureArchive" Version="1.0.0" />
<PackageReference Include="TVE.PureArchive" />
paket add TVE.PureArchive --version 1.0.0
#r "nuget: TVE.PureArchive, 1.0.0"
#:package TVE.PureArchive@1.0.0
#addin nuget:?package=TVE.PureArchive&version=1.0.0
#tool nuget:?package=TVE.PureArchive&version=1.0.0
TVE.PureArchive
Thư viện nén/giải nén cho .NET, giấy phép MIT.
1.0.0 — ZIP (read/write/update/repair/diff), Tar, GZip, BZip2 tự implement, WinZip AES + AES-256-GCM, lớp an toàn bật sẵn, pipeline song song, DI. Mọi định dạng được kiểm chứng hai chiều với các implementation độc lập bên ngoài — không phải tự round-trip với chính mình.
Chưa có: Zstd/LZMA, split volume, signing,
IFileProvider— xem Chưa có trong 1.0.0.
Định vị
Đã có sẵn vài thư viện nén tốt cho .NET, kể cả trong chính BCL. Thư viện này không nhắm "làm lại nhưng nhanh hơn" — khoảng trống thật nằm ở chỗ khác:
| Khoảng trống | PureArchive | |
|---|---|---|
| 0 | Mã hoá được kiểm chứng chéo, không phải tự round-trip. | WinZip AES-128/192/256 (AE-1/AE-2) đối chiếu hai chiều với hai implementation độc lập, viết bằng hai ngôn ngữ khác nhau, ở cả ba key size. Một counter endianness sai vẫn round-trip hoàn hảo với chính nó, và hai thư viện cùng đọc sai spec vẫn khớp nhau — nên cần hai tác giả khác nhau, không phải một. Cộng chế độ PureArchiveAes256Gcm: AEAD theo chunk, index và cờ end-of-stream được xác thực nên không thể cắt đuôi hay đảo thứ tự. |
| 1 | An toàn khi giải nén archive không tin cậy. Zip-slip và zip bomb có tiền lệ CVE trong hệ sinh thái, và giới hạn ratio/quota thường không bật sẵn. | ExtractionOptions.Default chặn zip-slip, zip bomb, symlink escape, reserved name, setuid, duplicate entry — mặc định, không cần cấu hình. ADR-0004 |
| 2 | Async thật + backpressure. | Pipeline System.Threading.Channels, backpressure theo bytes in-flight, CancellationToken xuyên suốt. Forward-only reader đọc được cả archive streamed dùng data descriptor. |
| 3 | Nén song song có kiểm soát memory. | Đo được 4.14× trên 8 core (nhiều entry) và 3.59× cho một file lớn (chia nhỏ trong entry). Backpressure theo bytes in-flight chứ không theo số item: parallelism budget = memory budget. |
| 4 | Ergonomics + observability. | DI profile qua named options chuẩn, IArchiveFactory mock được, IProgress, ActivitySource/Meter. Tên profile lạ bị từ chối thay vì âm thầm rơi về mặc định không mã hoá. |
| 5 | Archive tái lập được. | Deterministic mode: timestamp cố định, entry sắp thứ tự, output byte-for-byte giống nhau bất kể số thread. |
Cộng thêm: zero native dependency → Native AOT, trimming và Blazor WASM đều chạy. ADR-0003
Điều thư viện này KHÔNG hứa
Deflate trong .NET được thực thi bởi compressor native mà runtime đã bundle. Chúng tôi không hứa nhanh hơn nó ở Deflate một luồng — và không cố. Lợi thế hiệu năng phải đến từ pipeline (song song, pooling, zero-copy), không từ codec: xem ADR-0003 D2.
Đo thật, 200 file × 64 KiB, Deflate, macOS arm64, một luồng (bench/TVE.PureArchive.Benchmarks):
| Mean | Allocated | |
|---|---|---|
| Deflate của BCL | 97.0 ms | 1.43 MB |
| TVE.PureArchive (tuần tự) | 95.6 ms | 1.48 MB |
Ngang BCL về cả thời gian và allocation, ở bản tuần tự. Đạt được nhờ ghi trực tiếp vào archive rồi patch local header khi đã biết CRC/size, thay vì buffer từng entry — buffer chỉ dùng cho nguồn không biết trước độ dài. Nén song song là phần cộng thêm lên trên con số này.
Benchmark trong repo vẫn chạy đối chiếu với các thư viện khác để con số không bị đọc trong chân không (ADR-0003 D2); tài liệu này chỉ không xếp hạng chúng.
BZip2 — và chỗ nó thua
BCL không có BZip2. Bind một thư viện native sẽ phá zero-native-dependency, nên nó được viết từ đầu bằng managed code: outer RLE, BWT bằng prefix doubling với counting sort, MTF + RLE2, rồi Huffman nhiều bảng. Kiểm chứng bằng hai implementation độc lập của bzip2, không bằng decoder của chính nó — round-trip tự thân không bắt được lỗi format mà cả hai nửa cùng mắc.
Corpus 8.470.362 byte source của repo này, level 9, một luồng, tốt nhất của 4 lần:
| Nén | Kích thước | Giải nén | |
|---|---|---|---|
| Bản tham chiếu (native C) | 15,7 MB/s | 2.030.343 | ~42 MB/s |
| TVE.PureArchive (managed) | 7,0 MB/s | 2.030.275 | 24,6 MB/s |
Chậm hơn bản native 2,2× khi nén và 1,7× khi giải nén — đó là giá của managed code không có native dependency, và tôi không giả vờ ngược lại. Kích thước chênh 71 byte, tức ngang nhau. So với các bản managed khác thì nén thuộc nhóm chậm nhất, giải nén nằm giữa. Nếu cần BZip2 vì phía nhận chỉ đọc được method 12 thì dùng; còn nếu chọn được thì Deflate nhanh hơn nhiều.
Có gì trong 1.0.0
ZIP: read / write / update / repair-recovery / diff · forward-only reader (đọc được archive streamed dùng data descriptor) · Zip64 · extra field được bảo toàn nguyên trạng.
Tên file non-ASCII: ưu tiên cờ UTF-8, rồi ArchiveOptions.FileNameEncoding nếu bạn cấu hình, rồi
đoán UTF-8 cho tool ghi UTF-8 mà quên set cờ, cuối cùng fallback CP437. CP437 được implement từ
bảng tra chứ không qua Encoding.GetEncoding(437), nên không cần package System.Text.Encoding.CodePages
và vẫn AOT sạch. Muốn CP1258 (archive tiếng Việt do các archiver cũ tạo) thì tự truyền encoding đó
vào FileNameEncoding — nó không phải fallback mặc định.
Codec: Store · Deflate · BZip2 (method 12) — tự implement managed, kiểm chứng bằng bzip2 thật.
Định dạng khác: Tar (ustar/GNU/PAX) · GZip · .tar.gz · .tar.bz2.
Mã hoá: WinZip AES-128/192/256 (AE-1/AE-2) · PureArchiveAes256Gcm (AEAD theo chunk) · ZipCrypto
chỉ đọc (ADR-0005 A1 giải thích vì sao không ghi).
Còn lại: extraction safety bật sẵn · async pipeline + nén song song (mức entry và trong-entry kiểu
chia nhỏ trong entry) · deterministic mode · DI · AOT/trim sạch · net8.0 + net9.0.
Chưa có trong 1.0.0
Đây là điều tôi nói rõ thay vì để bạn cài rồi mới phát hiện:
| Trạng thái | |
|---|---|
| Zstd (method 93), LZMA (method 14) | Chưa có. Kế hoạch M4. |
Split volume (multi-volume .z01/.001) |
Chưa có. ArchiveOptions.Split tồn tại nhưng ném UnsupportedFeatureException. |
Signing (IArchiveSigner, CMS, RFC 3161) |
Chưa có. ArchiveOptions.Signing tồn tại nhưng ném UnsupportedFeatureException. |
IFileProvider adapter |
Chưa có. Kế hoạch M5. |
Hai dòng in đậm là public API hiện chỉ để ném — chúng có mặt để giữ chỗ hình dạng, không phải để dùng.
Không có, và đây là quyết định chứ không phải thiếu sót: RAR · 7z write · ISO · CAB · SFX · Brotli-in-ZIP (không có method ID trong APPNOTE — sẽ tạo file không tool nào đọc được) · Deflate64 encode · mount vào OS (FUSE/WinFsp) · binary delta patch · memory-mapped I/O (đến khi có benchmark chứng minh) · native P/Invoke.
Tài liệu
- Design review & phản biện — phân tích 2 tài liệu gốc
- API spec v3 — bề mặt API, mọi ví dụ đều biên dịch được
- ADR — 6 quyết định kiến trúc
- Roadmap — M1…M5, gate của từng milestone
Repo
src/ TVE.PureArchive.Abstractions | .PureArchive | .DependencyInjection
tests/ UnitTests | SecurityTests (ADR-0004) | InteropTests (ADR-0005 D7)
PipelineTests | DependencyInjectionTests | Fuzz (coverage-guided + replay)
bench/ Benchmarks | CorpusReport (ratio + throughput, corpus Canterbury/Silesia)
docs/ design review, API spec, ADR, ApiSketch (compile-proof cho mọi ví dụ)
eng/ gate: no-native-interop, no-forbidden-sources, update-public-api, coverage, fetch-corpus
dotnet build && dotnet test
333 test, coverage 84.91% lines / 86.15% branches. SecurityTests là 31 test tấn công thật (zip-slip 6 biến thể, absolute/UNC/drive path,
reserved device name, ADS, trailing dot, zip bomb, quota per-entry/tổng/số entry, duplicate entry) —
mỗi test yêu cầu throw đúng loại exception, không phải "không crash".
InteropTests kiểm chứng hai chiều với 4 tool ngoài; tool thiếu thì test Skip có ghi lý do,
không bao giờ pass âm thầm. PipelineTests khoá bất biến của M2: song song ≡ tuần tự byte-for-byte,
FIFO/chống bỏ đói của ByteBudget, và không rò spill file khi lỗi hoặc cancel giữa pipeline.
Mutation fuzzing xác định khoá hợp đồng exception: chỉ PureArchiveException và
OperationCanceledException được phép thoát ra. tests/TVE.PureArchive.Fuzz chạy fuzzing
coverage-guided theo lịch, và chạy replay xác định mỗi PR — cùng bộ mutate, nên gate trong repo không yếu
hơn gate trong CI.
Giấy phép
MIT. Code port vào đây chỉ được lấy từ nguồn public-domain hoặc MIT tương thích.
Hai nguồn bị cấm tuyệt đối, và đây là ràng buộc license chứ không phải sở thích: unrar (license của
nó cấm dùng để tạo compressor tương thích RAR) và p7zip (LGPL, không tương thích MIT).
eng/check-no-forbidden-sources.sh kiểm điều này trong CI mỗi lần chạy.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- System.IO.Hashing (>= 9.0.0)
- TVE.PureArchive.Abstractions (>= 1.0.0)
-
net9.0
- System.IO.Hashing (>= 9.0.0)
- TVE.PureArchive.Abstractions (>= 1.0.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on TVE.PureArchive:
| Package | Downloads |
|---|---|
|
TVE.PureArchive.DependencyInjection
Dependency injection integration for TVE.PureArchive: named profiles and IArchiveFactory. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 123 | 8/23/2026 |