omnizip 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +32 -0
- data/.rubocop_todo.yml +754 -0
- data/COPYING +502 -0
- data/Gemfile +17 -0
- data/LICENSE +12 -0
- data/README.adoc +1045 -0
- data/Rakefile +12 -0
- data/benchmark/README.md +260 -0
- data/benchmark/benchmark_suite.rb +125 -0
- data/benchmark/compression_bench.rb +181 -0
- data/benchmark/filter_bench.rb +180 -0
- data/benchmark/models/benchmark_result.rb +59 -0
- data/benchmark/models/comparison_result.rb +69 -0
- data/benchmark/profile_suite.rb +167 -0
- data/benchmark/reporter.rb +150 -0
- data/benchmark/run_benchmarks.rb +66 -0
- data/benchmark/test_data.rb +137 -0
- data/config/formats/rar3_spec.yml +91 -0
- data/config/formats/rar5_spec.yml +102 -0
- data/docs/.github/workflows/docs.yml +142 -0
- data/docs/.gitignore +21 -0
- data/docs/.lychee.toml +67 -0
- data/docs/Gemfile +13 -0
- data/docs/RAR_WRITE_SUPPORT.md +26 -0
- data/docs/README.md +101 -0
- data/docs/_config.yml +112 -0
- data/docs/assets/logo.svg +1 -0
- data/docs/assets/omnizip-logo.pdf +1540 -11
- data/docs/comparison/feature-matrix.adoc +694 -0
- data/docs/comparison/index.adoc +113 -0
- data/docs/comparison/vs-7zip.adoc +309 -0
- data/docs/comparison/vs-peazip.adoc +77 -0
- data/docs/comparison/vs-rubyzip.adoc +342 -0
- data/docs/comparison/vs-winrar.adoc +100 -0
- data/docs/compatibility.adoc +579 -0
- data/docs/concepts/index.adoc +129 -0
- data/docs/developer/architecture.adoc +256 -0
- data/docs/developer/contributing.adoc +158 -0
- data/docs/developer/index.adoc +25 -0
- data/docs/developer/testing.adoc +212 -0
- data/docs/getting-started/basic-usage.adoc +271 -0
- data/docs/getting-started/index.adoc +42 -0
- data/docs/getting-started/installation.adoc +138 -0
- data/docs/getting-started/quick-start.adoc +185 -0
- data/docs/getting-started/your-first-archive.adoc +218 -0
- data/docs/guides/advanced-features/encryption.adoc +300 -0
- data/docs/guides/advanced-features/index.adoc +49 -0
- data/docs/guides/advanced-features/parallel-processing.adoc +246 -0
- data/docs/guides/advanced-features/progress-tracking.adoc +320 -0
- data/docs/guides/advanced-features/streaming.adoc +212 -0
- data/docs/guides/archive-formats/gzip-format.adoc +107 -0
- data/docs/guides/archive-formats/index.adoc +130 -0
- data/docs/guides/archive-formats/rar-format.adoc +104 -0
- data/docs/guides/archive-formats/rar5.adoc +521 -0
- data/docs/guides/archive-formats/seven-zip-format.adoc +35 -0
- data/docs/guides/archive-formats/tar-format.adoc +106 -0
- data/docs/guides/archive-formats/xz-format.adoc +118 -0
- data/docs/guides/archive-formats/zip-format.adoc +35 -0
- data/docs/guides/compression-algorithms/bzip2.adoc +113 -0
- data/docs/guides/compression-algorithms/deflate.adoc +319 -0
- data/docs/guides/compression-algorithms/index.adoc +190 -0
- data/docs/guides/compression-algorithms/lzma.adoc +398 -0
- data/docs/guides/compression-algorithms/lzma2.adoc +327 -0
- data/docs/guides/compression-algorithms/ppmd.adoc +316 -0
- data/docs/guides/compression-algorithms/zstandard.adoc +361 -0
- data/docs/guides/creating-archives.adoc +354 -0
- data/docs/guides/extracting-archives.adoc +53 -0
- data/docs/guides/format-conversion.adoc +64 -0
- data/docs/guides/index.adoc +49 -0
- data/docs/guides/migration-rubyzip.adoc +217 -0
- data/docs/guides/parity-archives.adoc +605 -0
- data/docs/guides/performance-tuning.adoc +88 -0
- data/docs/index.adoc +218 -0
- data/docs/lychee.toml +67 -0
- data/docs/reference/api/overview.adoc +188 -0
- data/docs/reference/cli/compress-command.adoc +114 -0
- data/docs/reference/cli/overview.adoc +140 -0
- data/docs/reference/index.adoc +26 -0
- data/docs/resources/faq.adoc +185 -0
- data/docs/resources/quick-reference.adoc +222 -0
- data/docs/troubleshooting/index.adoc +208 -0
- data/examples/api_comparison.rb +205 -0
- data/examples/deflate64_example.rb +96 -0
- data/examples/par2_demo.rb +121 -0
- data/examples/quick_start_native.rb +150 -0
- data/examples/quick_start_rubyzip.rb +115 -0
- data/examples/rubyzip_compatibility_demo.rb +194 -0
- data/exe/omnizip +27 -0
- data/lib/omnizip/algorithm.rb +130 -0
- data/lib/omnizip/algorithm_registry.rb +86 -0
- data/lib/omnizip/algorithms/.keep +0 -0
- data/lib/omnizip/algorithms/bzip2/bwt.rb +225 -0
- data/lib/omnizip/algorithms/bzip2/decoder.rb +193 -0
- data/lib/omnizip/algorithms/bzip2/encoder.rb +237 -0
- data/lib/omnizip/algorithms/bzip2/huffman.rb +206 -0
- data/lib/omnizip/algorithms/bzip2/mtf.rb +101 -0
- data/lib/omnizip/algorithms/bzip2/rle.rb +151 -0
- data/lib/omnizip/algorithms/bzip2.rb +130 -0
- data/lib/omnizip/algorithms/deflate/constants.rb +28 -0
- data/lib/omnizip/algorithms/deflate/decoder.rb +38 -0
- data/lib/omnizip/algorithms/deflate/encoder.rb +46 -0
- data/lib/omnizip/algorithms/deflate.rb +128 -0
- data/lib/omnizip/algorithms/deflate64/constants.rb +45 -0
- data/lib/omnizip/algorithms/deflate64/decoder.rb +153 -0
- data/lib/omnizip/algorithms/deflate64/encoder.rb +98 -0
- data/lib/omnizip/algorithms/deflate64/huffman_coder.rb +354 -0
- data/lib/omnizip/algorithms/deflate64/lz77_encoder.rb +142 -0
- data/lib/omnizip/algorithms/deflate64.rb +109 -0
- data/lib/omnizip/algorithms/lzma/bit_model.rb +120 -0
- data/lib/omnizip/algorithms/lzma/constants.rb +112 -0
- data/lib/omnizip/algorithms/lzma/decoder.rb +148 -0
- data/lib/omnizip/algorithms/lzma/dictionary.rb +69 -0
- data/lib/omnizip/algorithms/lzma/distance_coder.rb +415 -0
- data/lib/omnizip/algorithms/lzma/encoder.rb +142 -0
- data/lib/omnizip/algorithms/lzma/length_coder.rb +260 -0
- data/lib/omnizip/algorithms/lzma/literal_decoder.rb +320 -0
- data/lib/omnizip/algorithms/lzma/literal_encoder.rb +210 -0
- data/lib/omnizip/algorithms/lzma/lzip_decoder.rb +341 -0
- data/lib/omnizip/algorithms/lzma/lzma_alone_decoder.rb +192 -0
- data/lib/omnizip/algorithms/lzma/lzma_state.rb +128 -0
- data/lib/omnizip/algorithms/lzma/match.rb +32 -0
- data/lib/omnizip/algorithms/lzma/match_finder.rb +205 -0
- data/lib/omnizip/algorithms/lzma/match_finder_config.rb +142 -0
- data/lib/omnizip/algorithms/lzma/match_finder_factory.rb +88 -0
- data/lib/omnizip/algorithms/lzma/optimal_encoder.rb +130 -0
- data/lib/omnizip/algorithms/lzma/probability_models.rb +72 -0
- data/lib/omnizip/algorithms/lzma/range_coder.rb +85 -0
- data/lib/omnizip/algorithms/lzma/range_decoder.rb +434 -0
- data/lib/omnizip/algorithms/lzma/range_encoder.rb +194 -0
- data/lib/omnizip/algorithms/lzma/state.rb +127 -0
- data/lib/omnizip/algorithms/lzma/xz_buffered_range_encoder.rb +325 -0
- data/lib/omnizip/algorithms/lzma/xz_encoder.rb +426 -0
- data/lib/omnizip/algorithms/lzma/xz_encoder_fast.rb +645 -0
- data/lib/omnizip/algorithms/lzma/xz_match_finder_adapter.rb +227 -0
- data/lib/omnizip/algorithms/lzma/xz_price_calculator.rb +169 -0
- data/lib/omnizip/algorithms/lzma/xz_probability_models.rb +261 -0
- data/lib/omnizip/algorithms/lzma/xz_range_encoder.rb +223 -0
- data/lib/omnizip/algorithms/lzma/xz_range_encoder_exact.rb +331 -0
- data/lib/omnizip/algorithms/lzma/xz_state.rb +116 -0
- data/lib/omnizip/algorithms/lzma/xz_utils_decoder.rb +2055 -0
- data/lib/omnizip/algorithms/lzma.rb +238 -0
- data/lib/omnizip/algorithms/lzma2/chunk_manager.rb +182 -0
- data/lib/omnizip/algorithms/lzma2/constants.rb +41 -0
- data/lib/omnizip/algorithms/lzma2/encoder.rb +147 -0
- data/lib/omnizip/algorithms/lzma2/lzma2_chunk.rb +161 -0
- data/lib/omnizip/algorithms/lzma2/properties.rb +179 -0
- data/lib/omnizip/algorithms/lzma2/simple_lzma2_encoder.rb +127 -0
- data/lib/omnizip/algorithms/lzma2/xz_encoder_adapter.rb +85 -0
- data/lib/omnizip/algorithms/lzma2.rb +141 -0
- data/lib/omnizip/algorithms/ppmd7/constants.rb +74 -0
- data/lib/omnizip/algorithms/ppmd7/context.rb +154 -0
- data/lib/omnizip/algorithms/ppmd7/decoder.rb +126 -0
- data/lib/omnizip/algorithms/ppmd7/encoder.rb +163 -0
- data/lib/omnizip/algorithms/ppmd7/model.rb +248 -0
- data/lib/omnizip/algorithms/ppmd7/symbol_state.rb +57 -0
- data/lib/omnizip/algorithms/ppmd7.rb +116 -0
- data/lib/omnizip/algorithms/ppmd8/constants.rb +61 -0
- data/lib/omnizip/algorithms/ppmd8/context.rb +34 -0
- data/lib/omnizip/algorithms/ppmd8/decoder.rb +107 -0
- data/lib/omnizip/algorithms/ppmd8/encoder.rb +138 -0
- data/lib/omnizip/algorithms/ppmd8/model.rb +250 -0
- data/lib/omnizip/algorithms/ppmd8/restoration_method.rb +78 -0
- data/lib/omnizip/algorithms/ppmd8.rb +82 -0
- data/lib/omnizip/algorithms/ppmd_base.rb +138 -0
- data/lib/omnizip/algorithms/sevenzip_lzma2.rb +123 -0
- data/lib/omnizip/algorithms/xz_lzma2.rb +118 -0
- data/lib/omnizip/algorithms/zstandard/constants.rb +25 -0
- data/lib/omnizip/algorithms/zstandard/decoder.rb +46 -0
- data/lib/omnizip/algorithms/zstandard/encoder.rb +51 -0
- data/lib/omnizip/algorithms/zstandard.rb +138 -0
- data/lib/omnizip/buffer/memory_archive.rb +251 -0
- data/lib/omnizip/buffer/memory_extractor.rb +224 -0
- data/lib/omnizip/buffer.rb +176 -0
- data/lib/omnizip/checksum_registry.rb +114 -0
- data/lib/omnizip/checksums/crc32.rb +100 -0
- data/lib/omnizip/checksums/crc64.rb +101 -0
- data/lib/omnizip/checksums/crc_base.rb +158 -0
- data/lib/omnizip/checksums/verifier.rb +131 -0
- data/lib/omnizip/chunked/memory_manager.rb +194 -0
- data/lib/omnizip/chunked/reader.rb +78 -0
- data/lib/omnizip/chunked/writer.rb +120 -0
- data/lib/omnizip/chunked.rb +129 -0
- data/lib/omnizip/cli/output_formatter.rb +104 -0
- data/lib/omnizip/cli.rb +572 -0
- data/lib/omnizip/commands/.keep +0 -0
- data/lib/omnizip/commands/archive_create_command.rb +427 -0
- data/lib/omnizip/commands/archive_extract_command.rb +272 -0
- data/lib/omnizip/commands/archive_list_command.rb +218 -0
- data/lib/omnizip/commands/archive_repair_command.rb +131 -0
- data/lib/omnizip/commands/archive_verify_command.rb +117 -0
- data/lib/omnizip/commands/compress_command.rb +117 -0
- data/lib/omnizip/commands/decompress_command.rb +120 -0
- data/lib/omnizip/commands/list_command.rb +53 -0
- data/lib/omnizip/commands/metadata_command.rb +153 -0
- data/lib/omnizip/commands/parity_create_command.rb +122 -0
- data/lib/omnizip/commands/parity_repair_command.rb +122 -0
- data/lib/omnizip/commands/parity_verify_command.rb +124 -0
- data/lib/omnizip/commands/profile_list_command.rb +56 -0
- data/lib/omnizip/commands/profile_show_command.rb +44 -0
- data/lib/omnizip/convenience.rb +359 -0
- data/lib/omnizip/converter/conversion_registry.rb +49 -0
- data/lib/omnizip/converter/conversion_strategy.rb +121 -0
- data/lib/omnizip/converter/seven_zip_to_zip_strategy.rb +97 -0
- data/lib/omnizip/converter/zip_to_seven_zip_strategy.rb +112 -0
- data/lib/omnizip/converter.rb +105 -0
- data/lib/omnizip/crypto/aes256/cipher.rb +100 -0
- data/lib/omnizip/crypto/aes256/constants.rb +28 -0
- data/lib/omnizip/crypto/aes256/key_derivation.rb +101 -0
- data/lib/omnizip/crypto/aes256.rb +102 -0
- data/lib/omnizip/error.rb +106 -0
- data/lib/omnizip/eta/exponential_smoothing_estimator.rb +98 -0
- data/lib/omnizip/eta/moving_average_estimator.rb +99 -0
- data/lib/omnizip/eta/rate_calculator.rb +104 -0
- data/lib/omnizip/eta/sample_history.rb +143 -0
- data/lib/omnizip/eta/time_estimator.rb +106 -0
- data/lib/omnizip/eta.rb +63 -0
- data/lib/omnizip/extraction/filter_chain.rb +177 -0
- data/lib/omnizip/extraction/glob_pattern.rb +140 -0
- data/lib/omnizip/extraction/pattern_matcher.rb +70 -0
- data/lib/omnizip/extraction/predicate_pattern.rb +52 -0
- data/lib/omnizip/extraction/regex_pattern.rb +50 -0
- data/lib/omnizip/extraction/selective_extractor.rb +240 -0
- data/lib/omnizip/extraction.rb +111 -0
- data/lib/omnizip/file_type/mime_classifier.rb +144 -0
- data/lib/omnizip/file_type.rb +113 -0
- data/lib/omnizip/filter.rb +139 -0
- data/lib/omnizip/filter_pipeline.rb +108 -0
- data/lib/omnizip/filter_registry.rb +166 -0
- data/lib/omnizip/filters/bcj.rb +279 -0
- data/lib/omnizip/filters/bcj2/constants.rb +53 -0
- data/lib/omnizip/filters/bcj2/decoder.rb +200 -0
- data/lib/omnizip/filters/bcj2/encoder.rb +61 -0
- data/lib/omnizip/filters/bcj2/stream_data.rb +93 -0
- data/lib/omnizip/filters/bcj2.rb +99 -0
- data/lib/omnizip/filters/bcj_arm.rb +176 -0
- data/lib/omnizip/filters/bcj_arm64.rb +244 -0
- data/lib/omnizip/filters/bcj_ia64.rb +196 -0
- data/lib/omnizip/filters/bcj_ppc.rb +190 -0
- data/lib/omnizip/filters/bcj_sparc.rb +176 -0
- data/lib/omnizip/filters/bcj_x86.rb +193 -0
- data/lib/omnizip/filters/delta.rb +196 -0
- data/lib/omnizip/filters/filter_base.rb +72 -0
- data/lib/omnizip/filters/registry.rb +123 -0
- data/lib/omnizip/filters/xz_delta.rb +258 -0
- data/lib/omnizip/format_detector.rb +162 -0
- data/lib/omnizip/format_registry.rb +59 -0
- data/lib/omnizip/formats/.keep +0 -0
- data/lib/omnizip/formats/bzip2_file.rb +172 -0
- data/lib/omnizip/formats/cpio/constants.rb +55 -0
- data/lib/omnizip/formats/cpio/entry.rb +385 -0
- data/lib/omnizip/formats/cpio/reader.rb +196 -0
- data/lib/omnizip/formats/cpio/writer.rb +234 -0
- data/lib/omnizip/formats/cpio.rb +140 -0
- data/lib/omnizip/formats/format_spec_loader.rb +230 -0
- data/lib/omnizip/formats/gzip.rb +238 -0
- data/lib/omnizip/formats/iso/directory_builder.rb +297 -0
- data/lib/omnizip/formats/iso/directory_record.rb +152 -0
- data/lib/omnizip/formats/iso/joliet.rb +204 -0
- data/lib/omnizip/formats/iso/path_table.rb +125 -0
- data/lib/omnizip/formats/iso/reader.rb +197 -0
- data/lib/omnizip/formats/iso/rock_ridge.rb +349 -0
- data/lib/omnizip/formats/iso/volume_builder.rb +320 -0
- data/lib/omnizip/formats/iso/volume_descriptor.rb +168 -0
- data/lib/omnizip/formats/iso/writer.rb +530 -0
- data/lib/omnizip/formats/iso.rb +140 -0
- data/lib/omnizip/formats/lzip.rb +175 -0
- data/lib/omnizip/formats/lzma_alone.rb +171 -0
- data/lib/omnizip/formats/rar/archive_repairer.rb +243 -0
- data/lib/omnizip/formats/rar/archive_verifier.rb +195 -0
- data/lib/omnizip/formats/rar/block_parser.rb +243 -0
- data/lib/omnizip/formats/rar/compression/bit_stream.rb +180 -0
- data/lib/omnizip/formats/rar/compression/dispatcher.rb +217 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/decoder.rb +216 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/encoder.rb +158 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_builder.rb +217 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_coder.rb +189 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/match_finder.rb +135 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/sliding_window.rb +165 -0
- data/lib/omnizip/formats/rar/compression/ppmd/context.rb +105 -0
- data/lib/omnizip/formats/rar/compression/ppmd/decoder.rb +219 -0
- data/lib/omnizip/formats/rar/compression/ppmd/encoder.rb +262 -0
- data/lib/omnizip/formats/rar/compression_method_registry.rb +106 -0
- data/lib/omnizip/formats/rar/constants.rb +82 -0
- data/lib/omnizip/formats/rar/decompressor.rb +238 -0
- data/lib/omnizip/formats/rar/external_writer.rb +312 -0
- data/lib/omnizip/formats/rar/header.rb +192 -0
- data/lib/omnizip/formats/rar/license_validator.rb +109 -0
- data/lib/omnizip/formats/rar/models/rar_archive.rb +77 -0
- data/lib/omnizip/formats/rar/models/rar_entry.rb +65 -0
- data/lib/omnizip/formats/rar/models/rar_volume.rb +56 -0
- data/lib/omnizip/formats/rar/parity_handler.rb +292 -0
- data/lib/omnizip/formats/rar/rar5/compression/lzma.rb +202 -0
- data/lib/omnizip/formats/rar/rar5/compression/lzss.rb +578 -0
- data/lib/omnizip/formats/rar/rar5/compression/store.rb +60 -0
- data/lib/omnizip/formats/rar/rar5/crc32.rb +39 -0
- data/lib/omnizip/formats/rar/rar5/encryption/aes256_cbc.rb +97 -0
- data/lib/omnizip/formats/rar/rar5/encryption/encryption_header.rb +114 -0
- data/lib/omnizip/formats/rar/rar5/encryption/encryption_manager.rb +166 -0
- data/lib/omnizip/formats/rar/rar5/encryption/key_derivation.rb +97 -0
- data/lib/omnizip/formats/rar/rar5/header.rb +187 -0
- data/lib/omnizip/formats/rar/rar5/models/encryption_options.rb +74 -0
- data/lib/omnizip/formats/rar/rar5/models/recovery_options.rb +63 -0
- data/lib/omnizip/formats/rar/rar5/models/solid_options.rb +63 -0
- data/lib/omnizip/formats/rar/rar5/models/volume_options.rb +74 -0
- data/lib/omnizip/formats/rar/rar5/multi_volume/ARCHITECTURE.md +290 -0
- data/lib/omnizip/formats/rar/rar5/multi_volume/volume_manager.rb +264 -0
- data/lib/omnizip/formats/rar/rar5/multi_volume/volume_splitter.rb +155 -0
- data/lib/omnizip/formats/rar/rar5/multi_volume/volume_writer.rb +194 -0
- data/lib/omnizip/formats/rar/rar5/solid/solid_encoder.rb +109 -0
- data/lib/omnizip/formats/rar/rar5/solid/solid_manager.rb +142 -0
- data/lib/omnizip/formats/rar/rar5/solid/solid_stream.rb +121 -0
- data/lib/omnizip/formats/rar/rar5/vint.rb +65 -0
- data/lib/omnizip/formats/rar/rar5/writer.rb +466 -0
- data/lib/omnizip/formats/rar/rar_format_base.rb +241 -0
- data/lib/omnizip/formats/rar/reader.rb +366 -0
- data/lib/omnizip/formats/rar/recovery_record.rb +245 -0
- data/lib/omnizip/formats/rar/volume_manager.rb +168 -0
- data/lib/omnizip/formats/rar/writer.rb +431 -0
- data/lib/omnizip/formats/rar.rb +205 -0
- data/lib/omnizip/formats/rar3/compressor.rb +73 -0
- data/lib/omnizip/formats/rar3/decompressor.rb +66 -0
- data/lib/omnizip/formats/rar3/reader.rb +386 -0
- data/lib/omnizip/formats/rar3/writer.rb +219 -0
- data/lib/omnizip/formats/rar5/compressor.rb +73 -0
- data/lib/omnizip/formats/rar5/decompressor.rb +66 -0
- data/lib/omnizip/formats/rar5/reader.rb +342 -0
- data/lib/omnizip/formats/rar5/writer.rb +214 -0
- data/lib/omnizip/formats/seven_zip/coder_chain.rb +150 -0
- data/lib/omnizip/formats/seven_zip/constants.rb +126 -0
- data/lib/omnizip/formats/seven_zip/encoded_header.rb +114 -0
- data/lib/omnizip/formats/seven_zip/encrypted_header.rb +142 -0
- data/lib/omnizip/formats/seven_zip/file_collector.rb +144 -0
- data/lib/omnizip/formats/seven_zip/header.rb +106 -0
- data/lib/omnizip/formats/seven_zip/header_encryptor.rb +134 -0
- data/lib/omnizip/formats/seven_zip/header_writer.rb +466 -0
- data/lib/omnizip/formats/seven_zip/models/coder_info.rb +30 -0
- data/lib/omnizip/formats/seven_zip/models/file_entry.rb +58 -0
- data/lib/omnizip/formats/seven_zip/models/folder.rb +69 -0
- data/lib/omnizip/formats/seven_zip/models/stream_info.rb +42 -0
- data/lib/omnizip/formats/seven_zip/parser.rb +660 -0
- data/lib/omnizip/formats/seven_zip/reader.rb +458 -0
- data/lib/omnizip/formats/seven_zip/split_archive_reader.rb +632 -0
- data/lib/omnizip/formats/seven_zip/split_archive_writer.rb +315 -0
- data/lib/omnizip/formats/seven_zip/stream_compressor.rb +151 -0
- data/lib/omnizip/formats/seven_zip/stream_decompressor.rb +162 -0
- data/lib/omnizip/formats/seven_zip/writer.rb +740 -0
- data/lib/omnizip/formats/seven_zip.rb +93 -0
- data/lib/omnizip/formats/tar/constants.rb +73 -0
- data/lib/omnizip/formats/tar/entry.rb +94 -0
- data/lib/omnizip/formats/tar/header.rb +168 -0
- data/lib/omnizip/formats/tar/reader.rb +121 -0
- data/lib/omnizip/formats/tar/writer.rb +216 -0
- data/lib/omnizip/formats/tar.rb +84 -0
- data/lib/omnizip/formats/xz/reader.rb +116 -0
- data/lib/omnizip/formats/xz.rb +237 -0
- data/lib/omnizip/formats/xz_impl/block_decoder.rb +754 -0
- data/lib/omnizip/formats/xz_impl/block_encoder.rb +306 -0
- data/lib/omnizip/formats/xz_impl/block_header.rb +210 -0
- data/lib/omnizip/formats/xz_impl/block_header_parser.rb +186 -0
- data/lib/omnizip/formats/xz_impl/constants.rb +49 -0
- data/lib/omnizip/formats/xz_impl/index_decoder.rb +174 -0
- data/lib/omnizip/formats/xz_impl/index_encoder.rb +122 -0
- data/lib/omnizip/formats/xz_impl/stream_decoder.rb +468 -0
- data/lib/omnizip/formats/xz_impl/stream_encoder.rb +99 -0
- data/lib/omnizip/formats/xz_impl/stream_footer.rb +81 -0
- data/lib/omnizip/formats/xz_impl/stream_footer_parser.rb +117 -0
- data/lib/omnizip/formats/xz_impl/stream_header.rb +55 -0
- data/lib/omnizip/formats/xz_impl/stream_header_parser.rb +108 -0
- data/lib/omnizip/formats/xz_impl/vli.rb +128 -0
- data/lib/omnizip/formats/xz_impl/writer.rb +421 -0
- data/lib/omnizip/formats/zip/central_directory_header.rb +195 -0
- data/lib/omnizip/formats/zip/constants.rb +69 -0
- data/lib/omnizip/formats/zip/end_of_central_directory.rb +133 -0
- data/lib/omnizip/formats/zip/local_file_header.rb +138 -0
- data/lib/omnizip/formats/zip/reader.rb +250 -0
- data/lib/omnizip/formats/zip/unix_extra_field.rb +153 -0
- data/lib/omnizip/formats/zip/writer.rb +375 -0
- data/lib/omnizip/formats/zip/zip64_end_of_central_directory.rb +104 -0
- data/lib/omnizip/formats/zip/zip64_end_of_central_directory_locator.rb +66 -0
- data/lib/omnizip/formats/zip/zip64_extra_field.rb +114 -0
- data/lib/omnizip/formats/zip.rb +50 -0
- data/lib/omnizip/implementations/base/lzma2_decoder_base.rb +75 -0
- data/lib/omnizip/implementations/base/lzma2_encoder_base.rb +128 -0
- data/lib/omnizip/implementations/base/lzma_decoder_base.rb +83 -0
- data/lib/omnizip/implementations/base/lzma_encoder_base.rb +108 -0
- data/lib/omnizip/implementations/base/state_machine_base.rb +182 -0
- data/lib/omnizip/implementations/seven_zip/lzma/decoder.rb +421 -0
- data/lib/omnizip/implementations/seven_zip/lzma/encoder.rb +465 -0
- data/lib/omnizip/implementations/seven_zip/lzma/match_finder.rb +288 -0
- data/lib/omnizip/implementations/seven_zip/lzma/range_decoder.rb +200 -0
- data/lib/omnizip/implementations/seven_zip/lzma/range_encoder.rb +197 -0
- data/lib/omnizip/implementations/seven_zip/lzma/state_machine.rb +141 -0
- data/lib/omnizip/implementations/seven_zip/lzma2/encoder.rb +519 -0
- data/lib/omnizip/implementations/xz_utils/lzma2/decoder.rb +723 -0
- data/lib/omnizip/implementations/xz_utils/lzma2/encoder.rb +750 -0
- data/lib/omnizip/io/buffered_input.rb +146 -0
- data/lib/omnizip/io/buffered_output.rb +105 -0
- data/lib/omnizip/io/stream_manager.rb +115 -0
- data/lib/omnizip/link_handler/hard_link.rb +79 -0
- data/lib/omnizip/link_handler/symbolic_link.rb +74 -0
- data/lib/omnizip/link_handler.rb +124 -0
- data/lib/omnizip/metadata/archive_metadata.rb +114 -0
- data/lib/omnizip/metadata/entry_metadata.rb +146 -0
- data/lib/omnizip/metadata/metadata_editor.rb +171 -0
- data/lib/omnizip/metadata/metadata_registry.rb +64 -0
- data/lib/omnizip/metadata/metadata_validator.rb +99 -0
- data/lib/omnizip/metadata.rb +57 -0
- data/lib/omnizip/models/.keep +0 -0
- data/lib/omnizip/models/algorithm_metadata.rb +73 -0
- data/lib/omnizip/models/compression_options.rb +71 -0
- data/lib/omnizip/models/conversion_options.rb +87 -0
- data/lib/omnizip/models/conversion_result.rb +135 -0
- data/lib/omnizip/models/eta_result.rb +46 -0
- data/lib/omnizip/models/extraction_rule.rb +115 -0
- data/lib/omnizip/models/filter_chain.rb +144 -0
- data/lib/omnizip/models/filter_config.rb +183 -0
- data/lib/omnizip/models/match_result.rb +124 -0
- data/lib/omnizip/models/optimization_suggestion.rb +91 -0
- data/lib/omnizip/models/parallel_options.rb +104 -0
- data/lib/omnizip/models/performance_result.rb +79 -0
- data/lib/omnizip/models/profile_report.rb +82 -0
- data/lib/omnizip/models/progress_options.rb +38 -0
- data/lib/omnizip/models/split_options.rb +116 -0
- data/lib/omnizip/optimization_registry.rb +81 -0
- data/lib/omnizip/parallel/job_queue.rb +209 -0
- data/lib/omnizip/parallel/job_scheduler.rb +203 -0
- data/lib/omnizip/parallel/parallel_compressor.rb +347 -0
- data/lib/omnizip/parallel/parallel_extractor.rb +329 -0
- data/lib/omnizip/parallel/worker_pool.rb +223 -0
- data/lib/omnizip/parallel.rb +149 -0
- data/lib/omnizip/parity/chunked_block_processor.rb +196 -0
- data/lib/omnizip/parity/galois16.rb +145 -0
- data/lib/omnizip/parity/models/creator_packet.rb +73 -0
- data/lib/omnizip/parity/models/file_description_packet.rb +133 -0
- data/lib/omnizip/parity/models/ifsc_packet.rb +123 -0
- data/lib/omnizip/parity/models/main_packet.rb +128 -0
- data/lib/omnizip/parity/models/packet.rb +156 -0
- data/lib/omnizip/parity/models/packet_registry.rb +109 -0
- data/lib/omnizip/parity/models/recovery_slice_packet.rb +78 -0
- data/lib/omnizip/parity/par2_creator.rb +531 -0
- data/lib/omnizip/parity/par2_repairer.rb +407 -0
- data/lib/omnizip/parity/par2_verifier.rb +364 -0
- data/lib/omnizip/parity/par2cmdline_algorithm.rb +110 -0
- data/lib/omnizip/parity/par2cmdline_coefficients.rb +78 -0
- data/lib/omnizip/parity/reed_solomon_decoder.rb +266 -0
- data/lib/omnizip/parity/reed_solomon_encoder.rb +111 -0
- data/lib/omnizip/parity/reed_solomon_matrix.rb +342 -0
- data/lib/omnizip/parity.rb +186 -0
- data/lib/omnizip/password/encryption_registry.rb +65 -0
- data/lib/omnizip/password/encryption_strategy.rb +96 -0
- data/lib/omnizip/password/password_validator.rb +129 -0
- data/lib/omnizip/password/winzip_aes_strategy.rb +192 -0
- data/lib/omnizip/password/zip_crypto_strategy.rb +141 -0
- data/lib/omnizip/password.rb +87 -0
- data/lib/omnizip/pipe/stream_compressor.rb +124 -0
- data/lib/omnizip/pipe/stream_decompressor.rb +174 -0
- data/lib/omnizip/pipe.rb +121 -0
- data/lib/omnizip/platform/ntfs_streams.rb +201 -0
- data/lib/omnizip/platform.rb +189 -0
- data/lib/omnizip/profile/archive_profile.rb +39 -0
- data/lib/omnizip/profile/balanced_profile.rb +33 -0
- data/lib/omnizip/profile/binary_profile.rb +36 -0
- data/lib/omnizip/profile/compression_profile.rb +158 -0
- data/lib/omnizip/profile/custom_profile.rb +157 -0
- data/lib/omnizip/profile/fast_profile.rb +33 -0
- data/lib/omnizip/profile/maximum_profile.rb +33 -0
- data/lib/omnizip/profile/profile_detector.rb +110 -0
- data/lib/omnizip/profile/profile_registry.rb +161 -0
- data/lib/omnizip/profile/text_profile.rb +36 -0
- data/lib/omnizip/profile.rb +190 -0
- data/lib/omnizip/profiler/memory_profiler.rb +66 -0
- data/lib/omnizip/profiler/method_profiler.rb +49 -0
- data/lib/omnizip/profiler/report_generator.rb +169 -0
- data/lib/omnizip/profiler.rb +204 -0
- data/lib/omnizip/progress/callback_reporter.rb +36 -0
- data/lib/omnizip/progress/console_reporter.rb +62 -0
- data/lib/omnizip/progress/log_reporter.rb +91 -0
- data/lib/omnizip/progress/operation_progress.rb +118 -0
- data/lib/omnizip/progress/progress_bar.rb +156 -0
- data/lib/omnizip/progress/progress_reporter.rb +40 -0
- data/lib/omnizip/progress/progress_tracker.rb +190 -0
- data/lib/omnizip/progress/silent_reporter.rb +24 -0
- data/lib/omnizip/progress.rb +127 -0
- data/lib/omnizip/rubyzip_compat.rb +63 -0
- data/lib/omnizip/temp/safe_extract.rb +168 -0
- data/lib/omnizip/temp/temp_file.rb +124 -0
- data/lib/omnizip/temp/temp_file_pool.rb +109 -0
- data/lib/omnizip/temp.rb +181 -0
- data/lib/omnizip/version.rb +5 -0
- data/lib/omnizip/zip/entry.rb +156 -0
- data/lib/omnizip/zip/file.rb +485 -0
- data/lib/omnizip/zip/input_stream.rb +273 -0
- data/lib/omnizip/zip/output_stream.rb +324 -0
- data/lib/omnizip.rb +156 -0
- data/readme-docs/advanced-features.adoc +515 -0
- data/readme-docs/api-usage.adoc +444 -0
- data/readme-docs/architecture.adoc +449 -0
- data/readme-docs/archive-formats.adoc +479 -0
- data/readme-docs/cli-usage.adoc +222 -0
- data/readme-docs/compression-algorithms.adoc +442 -0
- data/readme-docs/compression-profiles.adoc +247 -0
- data/readme-docs/encryption-checksums.adoc +328 -0
- data/readme-docs/format-converter.adoc +325 -0
- data/readme-docs/installation.adoc +228 -0
- data/readme-docs/par2-archives.adoc +608 -0
- data/readme-docs/performance-profiler.adoc +389 -0
- data/readme-docs/preprocessing-filters.adoc +280 -0
- data/xz-file-format-1.2.1.txt +1174 -0
- metadata +617 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2024 Ribose Inc.
|
|
5
|
+
#
|
|
6
|
+
# This file is part of Omnizip.
|
|
7
|
+
#
|
|
8
|
+
# Omnizip is a pure Ruby port of 7-Zip compression algorithms.
|
|
9
|
+
# Based on the 7-Zip LZMA SDK by Igor Pavlov.
|
|
10
|
+
#
|
|
11
|
+
# This library is free software; you can redistribute it and/or
|
|
12
|
+
# modify it under the terms of the GNU Lesser General Public
|
|
13
|
+
# License as published by the Free Software Foundation; either
|
|
14
|
+
# version 2.1 of the License, or (at your option) any later version.
|
|
15
|
+
#
|
|
16
|
+
# See the COPYING file for the complete text of the license.
|
|
17
|
+
#
|
|
18
|
+
|
|
19
|
+
module Omnizip
|
|
20
|
+
# Registry for managing available checksum algorithms.
|
|
21
|
+
#
|
|
22
|
+
# This class maintains a central registry of all checksum implementations
|
|
23
|
+
# available in Omnizip, providing a consistent interface for algorithm
|
|
24
|
+
# discovery and instantiation.
|
|
25
|
+
#
|
|
26
|
+
# The registry pattern ensures that checksum algorithms are defined in
|
|
27
|
+
# one place and can be easily extended with new implementations without
|
|
28
|
+
# modifying existing code.
|
|
29
|
+
#
|
|
30
|
+
# @example Register a new checksum algorithm
|
|
31
|
+
# ChecksumRegistry.register(:crc32, Omnizip::Checksums::Crc32)
|
|
32
|
+
#
|
|
33
|
+
# @example Get a checksum class
|
|
34
|
+
# crc_class = ChecksumRegistry.get(:crc32)
|
|
35
|
+
# checksum = crc_class.calculate("data")
|
|
36
|
+
#
|
|
37
|
+
# @example List available checksums
|
|
38
|
+
# ChecksumRegistry.available
|
|
39
|
+
# # => [:crc32, :crc64]
|
|
40
|
+
class ChecksumRegistry
|
|
41
|
+
@checksums = {}
|
|
42
|
+
|
|
43
|
+
class << self
|
|
44
|
+
# Register a checksum algorithm.
|
|
45
|
+
#
|
|
46
|
+
# Adds a new checksum implementation to the registry, making it
|
|
47
|
+
# available for use throughout the application.
|
|
48
|
+
#
|
|
49
|
+
# @param name [Symbol] unique identifier for the checksum
|
|
50
|
+
# @param checksum_class [Class] class implementing the checksum
|
|
51
|
+
# @return [void]
|
|
52
|
+
# @raise [ArgumentError] if name is already registered
|
|
53
|
+
def register(name, checksum_class)
|
|
54
|
+
name = name.to_sym
|
|
55
|
+
if @checksums.key?(name)
|
|
56
|
+
raise ArgumentError,
|
|
57
|
+
"Checksum '#{name}' is already registered"
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
@checksums[name] = checksum_class
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Retrieve a checksum class by name.
|
|
64
|
+
#
|
|
65
|
+
# Returns the checksum class registered under the given name,
|
|
66
|
+
# allowing for instantiation and use.
|
|
67
|
+
#
|
|
68
|
+
# @param name [Symbol] identifier of the checksum to retrieve
|
|
69
|
+
# @return [Class] the checksum class
|
|
70
|
+
# @raise [UnknownAlgorithmError] if checksum not found
|
|
71
|
+
def get(name)
|
|
72
|
+
name = name.to_sym
|
|
73
|
+
checksum_class = @checksums[name]
|
|
74
|
+
|
|
75
|
+
unless checksum_class
|
|
76
|
+
raise UnknownAlgorithmError,
|
|
77
|
+
"Unknown checksum: '#{name}'. Available: " \
|
|
78
|
+
"#{available.join(', ')}"
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
checksum_class
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# List all available checksum algorithms.
|
|
85
|
+
#
|
|
86
|
+
# Returns an array of registered checksum names, useful for
|
|
87
|
+
# displaying options to users or validating input.
|
|
88
|
+
#
|
|
89
|
+
# @return [Array<Symbol>] array of registered checksum names
|
|
90
|
+
def available
|
|
91
|
+
@checksums.keys.sort
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Check if a checksum is registered.
|
|
95
|
+
#
|
|
96
|
+
# @param name [Symbol] identifier of the checksum to check
|
|
97
|
+
# @return [Boolean] true if registered, false otherwise
|
|
98
|
+
def registered?(name)
|
|
99
|
+
@checksums.key?(name.to_sym)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Clear all registered checksums.
|
|
103
|
+
#
|
|
104
|
+
# This method is primarily for testing purposes and should not
|
|
105
|
+
# be used in production code.
|
|
106
|
+
#
|
|
107
|
+
# @return [void]
|
|
108
|
+
# @api private
|
|
109
|
+
def clear
|
|
110
|
+
@checksums.clear
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2024 Ribose Inc.
|
|
5
|
+
#
|
|
6
|
+
# This file is part of Omnizip.
|
|
7
|
+
#
|
|
8
|
+
# Omnizip is a pure Ruby port of 7-Zip compression algorithms.
|
|
9
|
+
# Based on the 7-Zip LZMA SDK by Igor Pavlov.
|
|
10
|
+
#
|
|
11
|
+
# This library is free software; you can redistribute it and/or
|
|
12
|
+
# modify it under the terms of the GNU Lesser General Public
|
|
13
|
+
# License as published by the Free Software Foundation; either
|
|
14
|
+
# version 2.1 of the License, or (at your option) any later version.
|
|
15
|
+
#
|
|
16
|
+
# See the COPYING file for the complete text of the license.
|
|
17
|
+
#
|
|
18
|
+
|
|
19
|
+
require_relative "crc_base"
|
|
20
|
+
|
|
21
|
+
module Omnizip
|
|
22
|
+
module Checksums
|
|
23
|
+
# CRC32 checksum implementation using IEEE 802.3 polynomial.
|
|
24
|
+
#
|
|
25
|
+
# This implementation uses the standard CRC32 polynomial (0xEDB88320)
|
|
26
|
+
# as used in 7-Zip, ZIP archives, PNG files, and Ethernet frames.
|
|
27
|
+
#
|
|
28
|
+
# The algorithm uses a 256-entry pre-computed lookup table for
|
|
29
|
+
# efficient O(1) per-byte processing, making it suitable for
|
|
30
|
+
# high-performance checksum calculation.
|
|
31
|
+
#
|
|
32
|
+
# Polynomial: 0xEDB88320 (reversed IEEE 802.3)
|
|
33
|
+
# Initial value: 0xFFFFFFFF
|
|
34
|
+
# Final XOR: 0xFFFFFFFF
|
|
35
|
+
# Bit width: 32
|
|
36
|
+
#
|
|
37
|
+
# @example One-shot calculation
|
|
38
|
+
# checksum = Omnizip::Checksums::Crc32.calculate("abc")
|
|
39
|
+
# # => 0x352441C2
|
|
40
|
+
#
|
|
41
|
+
# @example Incremental calculation
|
|
42
|
+
# crc = Omnizip::Checksums::Crc32.new
|
|
43
|
+
# crc.update("Hello, ")
|
|
44
|
+
# crc.update("world!")
|
|
45
|
+
# result = crc.finalize
|
|
46
|
+
class Crc32 < CrcBase
|
|
47
|
+
# IEEE 802.3 polynomial (reversed representation)
|
|
48
|
+
# This is the standard polynomial used in 7-Zip and ZIP files
|
|
49
|
+
POLYNOMIAL = 0xEDB88320
|
|
50
|
+
|
|
51
|
+
# 32-bit mask for truncating values
|
|
52
|
+
MASK_32 = 0xFFFFFFFF
|
|
53
|
+
|
|
54
|
+
# Pre-computed lookup table for CRC32 calculation
|
|
55
|
+
# Generated using the IEEE 802.3 polynomial
|
|
56
|
+
# This table is computed once at class load time for performance
|
|
57
|
+
TABLE = generate_table(POLYNOMIAL, 32).freeze
|
|
58
|
+
|
|
59
|
+
# Process a single byte through the CRC32 algorithm.
|
|
60
|
+
#
|
|
61
|
+
# Uses the lookup table for efficient computation:
|
|
62
|
+
# new_crc = (old_crc >> 8) ^ table[(old_crc ^ byte) & 0xFF]
|
|
63
|
+
#
|
|
64
|
+
# @param crc [Integer] current CRC value
|
|
65
|
+
# @param byte [Integer] byte to process (0-255)
|
|
66
|
+
# @return [Integer] updated CRC value
|
|
67
|
+
def process_byte(crc, byte)
|
|
68
|
+
index = (crc ^ byte) & 0xFF
|
|
69
|
+
(crc >> 8) ^ TABLE[index]
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Get the initial CRC32 value.
|
|
73
|
+
#
|
|
74
|
+
# CRC32 starts with all bits set to 1, which helps detect
|
|
75
|
+
# leading zeros in the data stream.
|
|
76
|
+
#
|
|
77
|
+
# @return [Integer] 0xFFFFFFFF
|
|
78
|
+
def initial_value
|
|
79
|
+
MASK_32
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Get the final XOR value for CRC32.
|
|
83
|
+
#
|
|
84
|
+
# The final result is XORed with all 1s to invert the bits,
|
|
85
|
+
# which is part of the CRC32 standard.
|
|
86
|
+
#
|
|
87
|
+
# @return [Integer] 0xFFFFFFFF
|
|
88
|
+
def final_xor
|
|
89
|
+
MASK_32
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Get the lookup table for CRC32.
|
|
93
|
+
#
|
|
94
|
+
# @return [Array<Integer>] 256-entry lookup table
|
|
95
|
+
def self.lookup_table
|
|
96
|
+
TABLE
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2024 Ribose Inc.
|
|
5
|
+
#
|
|
6
|
+
# This file is part of Omnizip.
|
|
7
|
+
#
|
|
8
|
+
# Omnizip is a pure Ruby port of 7-Zip compression algorithms.
|
|
9
|
+
# Based on the 7-Zip LZMA SDK by Igor Pavlov.
|
|
10
|
+
#
|
|
11
|
+
# This library is free software; you can redistribute it and/or
|
|
12
|
+
# modify it under the terms of the GNU Lesser General Public
|
|
13
|
+
# License as published by the Free Software Foundation; either
|
|
14
|
+
# version 2.1 of the License, or (at your option) any later version.
|
|
15
|
+
#
|
|
16
|
+
# See the COPYING file for the complete text of the license.
|
|
17
|
+
#
|
|
18
|
+
|
|
19
|
+
require_relative "crc_base"
|
|
20
|
+
|
|
21
|
+
module Omnizip
|
|
22
|
+
module Checksums
|
|
23
|
+
# CRC64 checksum implementation using ECMA-182 polynomial.
|
|
24
|
+
#
|
|
25
|
+
# This implementation uses the ECMA-182 polynomial for CRC64 calculation
|
|
26
|
+
# as used in the XZ file format and 7-Zip archives. This is the standard
|
|
27
|
+
# 64-bit CRC polynomial for data integrity verification in compressed
|
|
28
|
+
# archives.
|
|
29
|
+
#
|
|
30
|
+
# The algorithm uses a 256-entry pre-computed lookup table with 64-bit
|
|
31
|
+
# values for efficient O(1) per-byte processing.
|
|
32
|
+
#
|
|
33
|
+
# Polynomial: 0xC96C5795D7870F42 (ECMA-182)
|
|
34
|
+
# Initial value: 0xFFFFFFFFFFFFFFFF
|
|
35
|
+
# Final XOR: 0xFFFFFFFFFFFFFFFF
|
|
36
|
+
# Bit width: 64
|
|
37
|
+
#
|
|
38
|
+
# @example One-shot calculation
|
|
39
|
+
# checksum = Omnizip::Checksums::Crc64.calculate("123456789")
|
|
40
|
+
# # => 0x995DC9BBDF1939FA
|
|
41
|
+
#
|
|
42
|
+
# @example Incremental calculation
|
|
43
|
+
# crc = Omnizip::Checksums::Crc64.new
|
|
44
|
+
# crc.update("Hello, ")
|
|
45
|
+
# crc.update("world!")
|
|
46
|
+
# result = crc.finalize
|
|
47
|
+
class Crc64 < CrcBase
|
|
48
|
+
# ECMA-182 polynomial (reversed representation)
|
|
49
|
+
# This is the standard polynomial used in XZ format
|
|
50
|
+
POLYNOMIAL = 0xC96C5795D7870F42
|
|
51
|
+
|
|
52
|
+
# 64-bit mask for truncating values
|
|
53
|
+
MASK_64 = 0xFFFFFFFFFFFFFFFF
|
|
54
|
+
|
|
55
|
+
# Pre-computed lookup table for CRC64 calculation
|
|
56
|
+
# Generated using the ECMA-182 polynomial
|
|
57
|
+
# This table is computed once at class load time for performance
|
|
58
|
+
TABLE = generate_table(POLYNOMIAL, 64).freeze
|
|
59
|
+
|
|
60
|
+
# Process a single byte through the CRC64 algorithm.
|
|
61
|
+
#
|
|
62
|
+
# Uses the lookup table for efficient computation:
|
|
63
|
+
# new_crc = (old_crc >> 8) ^ table[(old_crc ^ byte) & 0xFF]
|
|
64
|
+
#
|
|
65
|
+
# @param crc [Integer] current CRC value
|
|
66
|
+
# @param byte [Integer] byte to process (0-255)
|
|
67
|
+
# @return [Integer] updated CRC value
|
|
68
|
+
def process_byte(crc, byte)
|
|
69
|
+
index = (crc ^ byte) & 0xFF
|
|
70
|
+
(crc >> 8) ^ TABLE[index]
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Get the initial CRC64 value.
|
|
74
|
+
#
|
|
75
|
+
# CRC64 starts with all bits set to 1, which helps detect
|
|
76
|
+
# leading zeros in the data stream.
|
|
77
|
+
#
|
|
78
|
+
# @return [Integer] 0xFFFFFFFFFFFFFFFF
|
|
79
|
+
def initial_value
|
|
80
|
+
MASK_64
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Get the final XOR value for CRC64.
|
|
84
|
+
#
|
|
85
|
+
# The final result is XORed with all 1s to invert the bits,
|
|
86
|
+
# which is part of the CRC64 standard.
|
|
87
|
+
#
|
|
88
|
+
# @return [Integer] 0xFFFFFFFFFFFFFFFF
|
|
89
|
+
def final_xor
|
|
90
|
+
MASK_64
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Get the lookup table for CRC64.
|
|
94
|
+
#
|
|
95
|
+
# @return [Array<Integer>] 256-entry lookup table
|
|
96
|
+
def self.lookup_table
|
|
97
|
+
TABLE
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2024 Ribose Inc.
|
|
5
|
+
#
|
|
6
|
+
# This file is part of Omnizip.
|
|
7
|
+
#
|
|
8
|
+
# Omnizip is a pure Ruby port of 7-Zip compression algorithms.
|
|
9
|
+
# Based on the 7-Zip LZMA SDK by Igor Pavlov.
|
|
10
|
+
#
|
|
11
|
+
# This library is free software; you can redistribute it and/or
|
|
12
|
+
# modify it under the terms of the GNU Lesser General Public
|
|
13
|
+
# License as published by the Free Software Foundation; either
|
|
14
|
+
# version 2.1 of the License, or (at your option) any later version.
|
|
15
|
+
#
|
|
16
|
+
# See the COPYING file for the complete text of the license.
|
|
17
|
+
#
|
|
18
|
+
|
|
19
|
+
module Omnizip
|
|
20
|
+
module Checksums
|
|
21
|
+
# Abstract base class for CRC (Cyclic Redundancy Check) algorithms.
|
|
22
|
+
#
|
|
23
|
+
# This class provides the common framework for implementing CRC
|
|
24
|
+
# checksums using lookup tables for efficient computation. Subclasses
|
|
25
|
+
# must define their specific polynomial and bit width.
|
|
26
|
+
#
|
|
27
|
+
# The lookup table approach provides O(1) per-byte processing time,
|
|
28
|
+
# making it significantly faster than bit-by-bit calculation.
|
|
29
|
+
#
|
|
30
|
+
# Architecture:
|
|
31
|
+
# - Pre-computed lookup tables stored as class constants
|
|
32
|
+
# - Incremental computation support via update method
|
|
33
|
+
# - Initial and final XOR values for standard CRC variants
|
|
34
|
+
#
|
|
35
|
+
# @abstract Subclass and override polynomial-specific methods
|
|
36
|
+
class CrcBase
|
|
37
|
+
# @return [Integer] current CRC value
|
|
38
|
+
attr_reader :value
|
|
39
|
+
|
|
40
|
+
# Initialize a new CRC calculator with default initial value.
|
|
41
|
+
#
|
|
42
|
+
# The initial value is typically all 1s (inverted 0) to detect
|
|
43
|
+
# leading zeros in the input data.
|
|
44
|
+
def initialize
|
|
45
|
+
@value = initial_value
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Update the CRC value with new data.
|
|
49
|
+
#
|
|
50
|
+
# This method processes the input data byte-by-byte using the
|
|
51
|
+
# lookup table, allowing incremental CRC calculation.
|
|
52
|
+
#
|
|
53
|
+
# @param data [String] binary string to process
|
|
54
|
+
# @return [self] for method chaining
|
|
55
|
+
def update(data)
|
|
56
|
+
data.each_byte do |byte|
|
|
57
|
+
@value = process_byte(@value, byte)
|
|
58
|
+
end
|
|
59
|
+
self
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Reset the CRC calculator to initial state.
|
|
63
|
+
#
|
|
64
|
+
# @return [self] for method chaining
|
|
65
|
+
def reset
|
|
66
|
+
@value = initial_value
|
|
67
|
+
self
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Get the finalized CRC value.
|
|
71
|
+
#
|
|
72
|
+
# Applies the final XOR operation required by most CRC standards
|
|
73
|
+
# to produce the final checksum value.
|
|
74
|
+
#
|
|
75
|
+
# @return [Integer] final CRC checksum
|
|
76
|
+
def finalize
|
|
77
|
+
@value ^ final_xor
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Calculate CRC for data in one operation.
|
|
81
|
+
#
|
|
82
|
+
# This is a convenience method that combines initialize, update,
|
|
83
|
+
# and finalize into a single call.
|
|
84
|
+
#
|
|
85
|
+
# @param data [String] binary string to checksum
|
|
86
|
+
# @return [Integer] final CRC checksum
|
|
87
|
+
def self.calculate(data)
|
|
88
|
+
new.update(data).finalize
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
protected
|
|
92
|
+
|
|
93
|
+
# Process a single byte through the CRC algorithm.
|
|
94
|
+
#
|
|
95
|
+
# This method must be implemented by subclasses to perform the
|
|
96
|
+
# actual CRC calculation using the lookup table.
|
|
97
|
+
#
|
|
98
|
+
# @param crc [Integer] current CRC value
|
|
99
|
+
# @param byte [Integer] byte to process (0-255)
|
|
100
|
+
# @return [Integer] updated CRC value
|
|
101
|
+
# @abstract
|
|
102
|
+
def process_byte(crc, byte)
|
|
103
|
+
raise NotImplementedError,
|
|
104
|
+
"#{self.class} must implement #process_byte"
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Get the initial CRC value.
|
|
108
|
+
#
|
|
109
|
+
# @return [Integer] initial value (typically all 1s)
|
|
110
|
+
# @abstract
|
|
111
|
+
def initial_value
|
|
112
|
+
raise NotImplementedError,
|
|
113
|
+
"#{self.class} must implement #initial_value"
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Get the final XOR value.
|
|
117
|
+
#
|
|
118
|
+
# @return [Integer] value to XOR with final result
|
|
119
|
+
# @abstract
|
|
120
|
+
def final_xor
|
|
121
|
+
raise NotImplementedError,
|
|
122
|
+
"#{self.class} must implement #final_xor"
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# Get the lookup table for this CRC variant.
|
|
126
|
+
#
|
|
127
|
+
# @return [Array<Integer>] 256-entry lookup table
|
|
128
|
+
# @abstract
|
|
129
|
+
def self.lookup_table
|
|
130
|
+
raise NotImplementedError,
|
|
131
|
+
"#{self} must implement .lookup_table"
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# Generate a CRC lookup table for given polynomial.
|
|
135
|
+
#
|
|
136
|
+
# This method pre-computes all possible CRC values for single-byte
|
|
137
|
+
# inputs, enabling efficient O(1) per-byte processing.
|
|
138
|
+
#
|
|
139
|
+
# @param polynomial [Integer] CRC polynomial
|
|
140
|
+
# @param bits [Integer] bit width (32 or 64)
|
|
141
|
+
# @return [Array<Integer>] 256-entry lookup table
|
|
142
|
+
def self.generate_table(polynomial, bits)
|
|
143
|
+
mask = (1 << bits) - 1
|
|
144
|
+
(0..255).map do |i|
|
|
145
|
+
crc = i
|
|
146
|
+
8.times do
|
|
147
|
+
if crc.anybits?(1)
|
|
148
|
+
crc = (crc >> 1) ^ polynomial
|
|
149
|
+
else
|
|
150
|
+
crc >>= 1
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
crc & mask
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright (C) 2025 Ribose Inc.
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
6
|
+
# copy of this software and associated documentation files (the "Software"),
|
|
7
|
+
# to deal in the Software without restriction, including without limitation
|
|
8
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
9
|
+
# and/or sell copies of the Software, and to permit persons to whom the
|
|
10
|
+
# Software is furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
|
13
|
+
# all copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
20
|
+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
21
|
+
# DEALINGS IN THE SOFTWARE.
|
|
22
|
+
|
|
23
|
+
require "zlib"
|
|
24
|
+
require "digest"
|
|
25
|
+
require_relative "crc64"
|
|
26
|
+
|
|
27
|
+
module Omnizip
|
|
28
|
+
module Checksums
|
|
29
|
+
# Checksum verification utilities for XZ format
|
|
30
|
+
#
|
|
31
|
+
# XZ supports multiple check types:
|
|
32
|
+
# - 0: None (no checksum)
|
|
33
|
+
# - 1: CRC32 (4 bytes)
|
|
34
|
+
# - 4: CRC64 (8 bytes)
|
|
35
|
+
# - 10: SHA256 (32 bytes)
|
|
36
|
+
class Verifier
|
|
37
|
+
# Check type constants (from XZ spec)
|
|
38
|
+
CHECK_NONE = 0
|
|
39
|
+
CHECK_CRC32 = 1
|
|
40
|
+
CHECK_CRC64 = 4
|
|
41
|
+
CHECK_SHA256 = 10
|
|
42
|
+
|
|
43
|
+
# Check sizes in bytes
|
|
44
|
+
CHECK_SIZES = {
|
|
45
|
+
CHECK_NONE => 0,
|
|
46
|
+
CHECK_CRC32 => 4,
|
|
47
|
+
CHECK_CRC64 => 8,
|
|
48
|
+
CHECK_SHA256 => 32,
|
|
49
|
+
}.freeze
|
|
50
|
+
|
|
51
|
+
# Verify CRC32 checksum
|
|
52
|
+
#
|
|
53
|
+
# @param data [String] Data to verify
|
|
54
|
+
# @param expected [Integer] Expected CRC32 value
|
|
55
|
+
# @return [Boolean] True if checksum matches
|
|
56
|
+
def self.verify_crc32(data, expected)
|
|
57
|
+
Zlib.crc32(data) == expected
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Verify CRC64 checksum
|
|
61
|
+
#
|
|
62
|
+
# @param data [String] Data to verify
|
|
63
|
+
# @param expected [Integer] Expected CRC64 value
|
|
64
|
+
# @return [Boolean] True if checksum matches
|
|
65
|
+
def self.verify_crc64(data, expected)
|
|
66
|
+
Crc64.calculate(data) == expected
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Verify SHA256 checksum
|
|
70
|
+
#
|
|
71
|
+
# @param data [String] Data to verify
|
|
72
|
+
# @param expected [String] Expected SHA256 digest (binary, 32 bytes)
|
|
73
|
+
# @return [Boolean] True if checksum matches
|
|
74
|
+
def self.verify_sha256(data, expected)
|
|
75
|
+
Digest::SHA256.digest(data) == expected
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Generic verify based on check type
|
|
79
|
+
#
|
|
80
|
+
# @param data [String] Data to verify
|
|
81
|
+
# @param expected [String] Expected checksum (binary format)
|
|
82
|
+
# @param check_type [Integer] Check type (0=None, 1=CRC32, 4=CRC64, 10=SHA256)
|
|
83
|
+
# @return [Boolean] True if checksum matches or check type is None
|
|
84
|
+
# @raise [ArgumentError] If check type is unknown
|
|
85
|
+
def self.verify(data, expected, check_type)
|
|
86
|
+
case check_type
|
|
87
|
+
when CHECK_NONE
|
|
88
|
+
true # No checksum to verify
|
|
89
|
+
when CHECK_CRC32
|
|
90
|
+
expected_crc = expected.unpack1("V")
|
|
91
|
+
verify_crc32(data, expected_crc)
|
|
92
|
+
when CHECK_CRC64
|
|
93
|
+
expected_crc = expected.unpack1("Q<")
|
|
94
|
+
verify_crc64(data, expected_crc)
|
|
95
|
+
when CHECK_SHA256
|
|
96
|
+
verify_sha256(data, expected)
|
|
97
|
+
else
|
|
98
|
+
raise "Unknown check type: #{check_type}"
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Get check size in bytes
|
|
103
|
+
#
|
|
104
|
+
# @param check_type [Integer] Check type
|
|
105
|
+
# @return [Integer] Size of checksum in bytes
|
|
106
|
+
def self.check_size(check_type)
|
|
107
|
+
CHECK_SIZES.fetch(check_type, 0)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Calculate checksum for data based on check type
|
|
111
|
+
#
|
|
112
|
+
# @param data [String] Data to checksum
|
|
113
|
+
# @param check_type [Integer] Check type
|
|
114
|
+
# @return [String] Checksum in binary format
|
|
115
|
+
def self.calculate(data, check_type)
|
|
116
|
+
case check_type
|
|
117
|
+
when CHECK_NONE
|
|
118
|
+
""
|
|
119
|
+
when CHECK_CRC32
|
|
120
|
+
[Zlib.crc32(data)].pack("V")
|
|
121
|
+
when CHECK_CRC64
|
|
122
|
+
[Crc64.calculate(data)].pack("Q<")
|
|
123
|
+
when CHECK_SHA256
|
|
124
|
+
Digest::SHA256.digest(data)
|
|
125
|
+
else
|
|
126
|
+
raise "Unknown check type: #{check_type}"
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|