omnizip 0.4.7-arm-linux

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.
Files changed (632) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +32 -0
  4. data/.rubocop_todo.yml +293 -0
  5. data/CHANGELOG.md +1647 -0
  6. data/CONTEXT.md +68 -0
  7. data/COPYING +502 -0
  8. data/Gemfile +19 -0
  9. data/LICENSE +12 -0
  10. data/README.adoc +1327 -0
  11. data/Rakefile +15 -0
  12. data/TODO.refactor/00-overview.md +67 -0
  13. data/TODO.refactor/01-registry-base-class.md +81 -0
  14. data/TODO.refactor/02-error-hierarchy.md +57 -0
  15. data/TODO.refactor/03-autoload-entry-point.md +69 -0
  16. data/TODO.refactor/04-filter-base-consolidation.md +49 -0
  17. data/TODO.refactor/05-send-private-methods.md +64 -0
  18. data/TODO.refactor/06-instance-variable-access.md +69 -0
  19. data/TODO.refactor/07-respond-to-replacement.md +237 -0
  20. data/TODO.refactor/08-spec-doubles.md +27 -0
  21. data/TODO.refactor/09-cli-shared-module.md +35 -0
  22. data/TODO.refactor/10-format-detector-ocp.md +34 -0
  23. data/TODO.refactor/11-convenience-decoupling.md +38 -0
  24. data/TODO.refactor/12-thread-safety.md +8 -0
  25. data/TODO.refactor/13-lutaml-model-migration.md +158 -0
  26. data/TODO.refactor/14-add-missing-specs.md +25 -0
  27. data/benchmark/README.md +260 -0
  28. data/benchmark/benchmark_suite.rb +125 -0
  29. data/benchmark/compression_bench.rb +181 -0
  30. data/benchmark/filter_bench.rb +180 -0
  31. data/benchmark/models/benchmark_result.rb +59 -0
  32. data/benchmark/models/comparison_result.rb +69 -0
  33. data/benchmark/profile_suite.rb +167 -0
  34. data/benchmark/reporter.rb +150 -0
  35. data/benchmark/run_benchmarks.rb +66 -0
  36. data/benchmark/test_data.rb +137 -0
  37. data/config/formats/rar3_spec.yml +92 -0
  38. data/config/formats/rar5_spec.yml +102 -0
  39. data/docs/.github/workflows/docs.yml +142 -0
  40. data/docs/.gitignore +21 -0
  41. data/docs/.lychee.toml +67 -0
  42. data/docs/Gemfile +13 -0
  43. data/docs/RAR_WRITE_SUPPORT.md +26 -0
  44. data/docs/README.md +101 -0
  45. data/docs/_config.yml +112 -0
  46. data/docs/assets/logo.svg +1 -0
  47. data/docs/assets/omnizip-logo.pdf +1540 -11
  48. data/docs/comparison/feature-matrix.adoc +694 -0
  49. data/docs/comparison/index.adoc +113 -0
  50. data/docs/comparison/vs-7zip.adoc +309 -0
  51. data/docs/comparison/vs-peazip.adoc +77 -0
  52. data/docs/comparison/vs-rubyzip.adoc +342 -0
  53. data/docs/comparison/vs-winrar.adoc +100 -0
  54. data/docs/compatibility.adoc +579 -0
  55. data/docs/concepts/index.adoc +129 -0
  56. data/docs/developer/architecture.adoc +256 -0
  57. data/docs/developer/contributing.adoc +158 -0
  58. data/docs/developer/index.adoc +25 -0
  59. data/docs/developer/testing.adoc +212 -0
  60. data/docs/getting-started/basic-usage.adoc +263 -0
  61. data/docs/getting-started/index.adoc +42 -0
  62. data/docs/getting-started/installation.adoc +138 -0
  63. data/docs/getting-started/quick-start.adoc +183 -0
  64. data/docs/getting-started/your-first-archive.adoc +219 -0
  65. data/docs/guides/advanced-features/encryption.adoc +277 -0
  66. data/docs/guides/advanced-features/index.adoc +59 -0
  67. data/docs/guides/advanced-features/parallel-processing.adoc +144 -0
  68. data/docs/guides/advanced-features/progress-tracking.adoc +124 -0
  69. data/docs/guides/advanced-features/streaming.adoc +142 -0
  70. data/docs/guides/archive-formats/gzip-format.adoc +105 -0
  71. data/docs/guides/archive-formats/index.adoc +160 -0
  72. data/docs/guides/archive-formats/ole-format.adoc +151 -0
  73. data/docs/guides/archive-formats/rar-format.adoc +104 -0
  74. data/docs/guides/archive-formats/rar5.adoc +521 -0
  75. data/docs/guides/archive-formats/rpm-format.adoc +108 -0
  76. data/docs/guides/archive-formats/seven-zip-format.adoc +35 -0
  77. data/docs/guides/archive-formats/tar-format.adoc +106 -0
  78. data/docs/guides/archive-formats/xz-format.adoc +118 -0
  79. data/docs/guides/archive-formats/zip-format.adoc +35 -0
  80. data/docs/guides/compression-algorithms/bzip2.adoc +114 -0
  81. data/docs/guides/compression-algorithms/deflate.adoc +313 -0
  82. data/docs/guides/compression-algorithms/index.adoc +190 -0
  83. data/docs/guides/compression-algorithms/lzma.adoc +394 -0
  84. data/docs/guides/compression-algorithms/lzma2.adoc +244 -0
  85. data/docs/guides/compression-algorithms/ppmd.adoc +313 -0
  86. data/docs/guides/compression-algorithms/zstandard.adoc +296 -0
  87. data/docs/guides/creating-archives.adoc +348 -0
  88. data/docs/guides/extracting-archives.adoc +53 -0
  89. data/docs/guides/format-conversion.adoc +64 -0
  90. data/docs/guides/index.adoc +49 -0
  91. data/docs/guides/migration-rubyzip.adoc +217 -0
  92. data/docs/guides/parity-archives.adoc +605 -0
  93. data/docs/guides/performance-tuning.adoc +88 -0
  94. data/docs/index.adoc +228 -0
  95. data/docs/lychee.toml +67 -0
  96. data/docs/reference/api/overview.adoc +187 -0
  97. data/docs/reference/cli/compress-command.adoc +114 -0
  98. data/docs/reference/cli/overview.adoc +140 -0
  99. data/docs/reference/index.adoc +26 -0
  100. data/docs/resources/faq.adoc +185 -0
  101. data/docs/resources/quick-reference.adoc +222 -0
  102. data/docs/rust-backend.md +0 -0
  103. data/docs/troubleshooting/index.adoc +207 -0
  104. data/docs/xar_format.md +216 -0
  105. data/examples/api_comparison.rb +205 -0
  106. data/examples/deflate64_example.rb +96 -0
  107. data/examples/par2_demo.rb +121 -0
  108. data/examples/quick_start_native.rb +150 -0
  109. data/examples/quick_start_rubyzip.rb +115 -0
  110. data/examples/rubyzip_compatibility_demo.rb +194 -0
  111. data/exe/omnizip +27 -0
  112. data/lib/omnizip/algorithm.rb +176 -0
  113. data/lib/omnizip/algorithm_registry.rb +65 -0
  114. data/lib/omnizip/algorithms/.keep +0 -0
  115. data/lib/omnizip/algorithms/bzip2/bwt.rb +236 -0
  116. data/lib/omnizip/algorithms/bzip2/bz2.rb +687 -0
  117. data/lib/omnizip/algorithms/bzip2/rle.rb +146 -0
  118. data/lib/omnizip/algorithms/bzip2.rb +108 -0
  119. data/lib/omnizip/algorithms/deflate/constants.rb +28 -0
  120. data/lib/omnizip/algorithms/deflate/decoder.rb +37 -0
  121. data/lib/omnizip/algorithms/deflate/encoder.rb +45 -0
  122. data/lib/omnizip/algorithms/deflate.rb +135 -0
  123. data/lib/omnizip/algorithms/deflate64/constants.rb +45 -0
  124. data/lib/omnizip/algorithms/deflate64/decoder.rb +151 -0
  125. data/lib/omnizip/algorithms/deflate64/encoder.rb +95 -0
  126. data/lib/omnizip/algorithms/deflate64/huffman_coder.rb +352 -0
  127. data/lib/omnizip/algorithms/deflate64/lz77_encoder.rb +140 -0
  128. data/lib/omnizip/algorithms/deflate64.rb +118 -0
  129. data/lib/omnizip/algorithms/lzma/bit_model.rb +120 -0
  130. data/lib/omnizip/algorithms/lzma/constants.rb +112 -0
  131. data/lib/omnizip/algorithms/lzma/decoder.rb +146 -0
  132. data/lib/omnizip/algorithms/lzma/dictionary.rb +70 -0
  133. data/lib/omnizip/algorithms/lzma/distance_coder.rb +326 -0
  134. data/lib/omnizip/algorithms/lzma/encoder.rb +139 -0
  135. data/lib/omnizip/algorithms/lzma/length_coder.rb +172 -0
  136. data/lib/omnizip/algorithms/lzma/literal_decoder.rb +204 -0
  137. data/lib/omnizip/algorithms/lzma/literal_encoder.rb +208 -0
  138. data/lib/omnizip/algorithms/lzma/lzip_decoder.rb +368 -0
  139. data/lib/omnizip/algorithms/lzma/lzma1_encoder.rb +105 -0
  140. data/lib/omnizip/algorithms/lzma/lzma_alone_decoder.rb +194 -0
  141. data/lib/omnizip/algorithms/lzma/lzma_state.rb +128 -0
  142. data/lib/omnizip/algorithms/lzma/match.rb +32 -0
  143. data/lib/omnizip/algorithms/lzma/match_finder.rb +233 -0
  144. data/lib/omnizip/algorithms/lzma/match_finder_config.rb +142 -0
  145. data/lib/omnizip/algorithms/lzma/match_finder_factory.rb +84 -0
  146. data/lib/omnizip/algorithms/lzma/optimal_encoder.rb +159 -0
  147. data/lib/omnizip/algorithms/lzma/probability_models.rb +72 -0
  148. data/lib/omnizip/algorithms/lzma/range_coder.rb +82 -0
  149. data/lib/omnizip/algorithms/lzma/range_decoder.rb +274 -0
  150. data/lib/omnizip/algorithms/lzma/range_encoder.rb +202 -0
  151. data/lib/omnizip/algorithms/lzma/state.rb +127 -0
  152. data/lib/omnizip/algorithms/lzma/xz_buffered_range_encoder.rb +323 -0
  153. data/lib/omnizip/algorithms/lzma/xz_encoder.rb +420 -0
  154. data/lib/omnizip/algorithms/lzma/xz_encoder_fast.rb +640 -0
  155. data/lib/omnizip/algorithms/lzma/xz_match_finder_adapter.rb +224 -0
  156. data/lib/omnizip/algorithms/lzma/xz_price_calculator.rb +167 -0
  157. data/lib/omnizip/algorithms/lzma/xz_probability_models.rb +258 -0
  158. data/lib/omnizip/algorithms/lzma/xz_range_encoder.rb +223 -0
  159. data/lib/omnizip/algorithms/lzma/xz_range_encoder_exact.rb +314 -0
  160. data/lib/omnizip/algorithms/lzma/xz_state.rb +108 -0
  161. data/lib/omnizip/algorithms/lzma/xz_utils_decoder.rb +1311 -0
  162. data/lib/omnizip/algorithms/lzma.rb +266 -0
  163. data/lib/omnizip/algorithms/lzma2/chunk_manager.rb +180 -0
  164. data/lib/omnizip/algorithms/lzma2/constants.rb +38 -0
  165. data/lib/omnizip/algorithms/lzma2/encoder.rb +145 -0
  166. data/lib/omnizip/algorithms/lzma2/lzma2_chunk.rb +165 -0
  167. data/lib/omnizip/algorithms/lzma2/properties.rb +179 -0
  168. data/lib/omnizip/algorithms/lzma2/simple_lzma2_encoder.rb +122 -0
  169. data/lib/omnizip/algorithms/lzma2/xz_encoder_adapter.rb +85 -0
  170. data/lib/omnizip/algorithms/lzma2.rb +133 -0
  171. data/lib/omnizip/algorithms/ppmd7/constants.rb +74 -0
  172. data/lib/omnizip/algorithms/ppmd7/context.rb +151 -0
  173. data/lib/omnizip/algorithms/ppmd7/decoder.rb +127 -0
  174. data/lib/omnizip/algorithms/ppmd7/encoder.rb +153 -0
  175. data/lib/omnizip/algorithms/ppmd7/model.rb +245 -0
  176. data/lib/omnizip/algorithms/ppmd7/symbol_state.rb +57 -0
  177. data/lib/omnizip/algorithms/ppmd7.rb +146 -0
  178. data/lib/omnizip/algorithms/ppmd8/constants.rb +61 -0
  179. data/lib/omnizip/algorithms/ppmd8/context.rb +32 -0
  180. data/lib/omnizip/algorithms/ppmd8/decoder.rb +104 -0
  181. data/lib/omnizip/algorithms/ppmd8/encoder.rb +135 -0
  182. data/lib/omnizip/algorithms/ppmd8/model.rb +246 -0
  183. data/lib/omnizip/algorithms/ppmd8/restoration_method.rb +78 -0
  184. data/lib/omnizip/algorithms/ppmd8.rb +122 -0
  185. data/lib/omnizip/algorithms/ppmd_base.rb +142 -0
  186. data/lib/omnizip/algorithms/registration.rb +28 -0
  187. data/lib/omnizip/algorithms/zstandard/constants.rb +158 -0
  188. data/lib/omnizip/algorithms/zstandard/decoder.rb +249 -0
  189. data/lib/omnizip/algorithms/zstandard/dictionary.rb +73 -0
  190. data/lib/omnizip/algorithms/zstandard/encoder.rb +294 -0
  191. data/lib/omnizip/algorithms/zstandard/frame/block.rb +143 -0
  192. data/lib/omnizip/algorithms/zstandard/frame/header.rb +233 -0
  193. data/lib/omnizip/algorithms/zstandard/frame.rb +33 -0
  194. data/lib/omnizip/algorithms/zstandard/fse/bitstream.rb +183 -0
  195. data/lib/omnizip/algorithms/zstandard/fse/encoder.rb +534 -0
  196. data/lib/omnizip/algorithms/zstandard/fse/interleaved.rb +92 -0
  197. data/lib/omnizip/algorithms/zstandard/fse/table.rb +188 -0
  198. data/lib/omnizip/algorithms/zstandard/fse/table_description.rb +203 -0
  199. data/lib/omnizip/algorithms/zstandard/fse.rb +53 -0
  200. data/lib/omnizip/algorithms/zstandard/huffman.rb +276 -0
  201. data/lib/omnizip/algorithms/zstandard/huffman_encoder.rb +327 -0
  202. data/lib/omnizip/algorithms/zstandard/ldm.rb +121 -0
  203. data/lib/omnizip/algorithms/zstandard/literals.rb +241 -0
  204. data/lib/omnizip/algorithms/zstandard/literals_encoder.rb +96 -0
  205. data/lib/omnizip/algorithms/zstandard/match_finder.rb +483 -0
  206. data/lib/omnizip/algorithms/zstandard/sequences.rb +350 -0
  207. data/lib/omnizip/algorithms/zstandard/sequences_encoder.rb +333 -0
  208. data/lib/omnizip/algorithms/zstandard/xxhash.rb +159 -0
  209. data/lib/omnizip/algorithms/zstandard.rb +210 -0
  210. data/lib/omnizip/algorithms.rb +35 -0
  211. data/lib/omnizip/archive/builder.rb +48 -0
  212. data/lib/omnizip/archive/reader_session.rb +67 -0
  213. data/lib/omnizip/archive.rb +86 -0
  214. data/lib/omnizip/archive_handler.rb +82 -0
  215. data/lib/omnizip/archive_handlers/cpio_handler.rb +47 -0
  216. data/lib/omnizip/archive_handlers/iso_handler.rb +54 -0
  217. data/lib/omnizip/archive_handlers/ole_handler.rb +37 -0
  218. data/lib/omnizip/archive_handlers/rar_handler.rb +96 -0
  219. data/lib/omnizip/archive_handlers/rpm_handler.rb +45 -0
  220. data/lib/omnizip/archive_handlers/seven_zip_handler.rb +89 -0
  221. data/lib/omnizip/archive_handlers/tar_handler.rb +75 -0
  222. data/lib/omnizip/archive_handlers/xar_handler.rb +49 -0
  223. data/lib/omnizip/archive_handlers/zip_handler.rb +115 -0
  224. data/lib/omnizip/archive_handlers.rb +18 -0
  225. data/lib/omnizip/backends.rb +160 -0
  226. data/lib/omnizip/buffer/memory_archive.rb +246 -0
  227. data/lib/omnizip/buffer/memory_extractor.rb +234 -0
  228. data/lib/omnizip/buffer/seven_zip_bridge.rb +171 -0
  229. data/lib/omnizip/buffer.rb +187 -0
  230. data/lib/omnizip/checksum_registry.rb +41 -0
  231. data/lib/omnizip/checksums/crc32.rb +101 -0
  232. data/lib/omnizip/checksums/crc64.rb +102 -0
  233. data/lib/omnizip/checksums/crc_base.rb +158 -0
  234. data/lib/omnizip/checksums/registration.rb +16 -0
  235. data/lib/omnizip/checksums/verifier.rb +130 -0
  236. data/lib/omnizip/checksums.rb +11 -0
  237. data/lib/omnizip/chunked/memory_manager.rb +194 -0
  238. data/lib/omnizip/chunked/reader.rb +78 -0
  239. data/lib/omnizip/chunked/writer.rb +123 -0
  240. data/lib/omnizip/chunked.rb +123 -0
  241. data/lib/omnizip/cli/output_formatter.rb +112 -0
  242. data/lib/omnizip/cli.rb +604 -0
  243. data/lib/omnizip/commands/.keep +0 -0
  244. data/lib/omnizip/commands/archive_create_command.rb +245 -0
  245. data/lib/omnizip/commands/archive_extract_command.rb +231 -0
  246. data/lib/omnizip/commands/archive_list_command.rb +204 -0
  247. data/lib/omnizip/commands/archive_repair_command.rb +129 -0
  248. data/lib/omnizip/commands/archive_verify_command.rb +115 -0
  249. data/lib/omnizip/commands/compress_command.rb +115 -0
  250. data/lib/omnizip/commands/decompress_command.rb +149 -0
  251. data/lib/omnizip/commands/list_command.rb +51 -0
  252. data/lib/omnizip/commands/metadata_command.rb +215 -0
  253. data/lib/omnizip/commands/parity_create_command.rb +114 -0
  254. data/lib/omnizip/commands/parity_repair_command.rb +120 -0
  255. data/lib/omnizip/commands/parity_verify_command.rb +122 -0
  256. data/lib/omnizip/commands/profile_list_command.rb +54 -0
  257. data/lib/omnizip/commands/profile_show_command.rb +44 -0
  258. data/lib/omnizip/commands.rb +21 -0
  259. data/lib/omnizip/convenience.rb +389 -0
  260. data/lib/omnizip/converter/conversion_registry.rb +50 -0
  261. data/lib/omnizip/converter/conversion_strategy.rb +108 -0
  262. data/lib/omnizip/converter/extract_repack_strategy.rb +51 -0
  263. data/lib/omnizip/converter/seven_zip_to_zip_strategy.rb +43 -0
  264. data/lib/omnizip/converter/zip_to_seven_zip_strategy.rb +54 -0
  265. data/lib/omnizip/converter.rb +124 -0
  266. data/lib/omnizip/crypto/aes256/cipher.rb +104 -0
  267. data/lib/omnizip/crypto/aes256/constants.rb +28 -0
  268. data/lib/omnizip/crypto/aes256/key_derivation.rb +100 -0
  269. data/lib/omnizip/crypto/aes256.rb +102 -0
  270. data/lib/omnizip/crypto.rb +11 -0
  271. data/lib/omnizip/entry.rb +44 -0
  272. data/lib/omnizip/error.rb +110 -0
  273. data/lib/omnizip/eta/exponential_smoothing_estimator.rb +95 -0
  274. data/lib/omnizip/eta/moving_average_estimator.rb +96 -0
  275. data/lib/omnizip/eta/rate_calculator.rb +104 -0
  276. data/lib/omnizip/eta/sample_history.rb +143 -0
  277. data/lib/omnizip/eta/time_estimator.rb +106 -0
  278. data/lib/omnizip/eta.rb +68 -0
  279. data/lib/omnizip/extraction/filter_chain.rb +179 -0
  280. data/lib/omnizip/extraction/glob_pattern.rb +140 -0
  281. data/lib/omnizip/extraction/pattern_matcher.rb +66 -0
  282. data/lib/omnizip/extraction/predicate_pattern.rb +52 -0
  283. data/lib/omnizip/extraction/regex_pattern.rb +50 -0
  284. data/lib/omnizip/extraction/selective_extractor.rb +247 -0
  285. data/lib/omnizip/extraction.rb +115 -0
  286. data/lib/omnizip/file_type/mime_classifier.rb +144 -0
  287. data/lib/omnizip/file_type.rb +117 -0
  288. data/lib/omnizip/filter.rb +141 -0
  289. data/lib/omnizip/filter_pipeline.rb +108 -0
  290. data/lib/omnizip/filter_registry.rb +113 -0
  291. data/lib/omnizip/filters/bcj.rb +277 -0
  292. data/lib/omnizip/filters/bcj2/constants.rb +53 -0
  293. data/lib/omnizip/filters/bcj2/decoder.rb +263 -0
  294. data/lib/omnizip/filters/bcj2/encoder.rb +58 -0
  295. data/lib/omnizip/filters/bcj2/stream_data.rb +91 -0
  296. data/lib/omnizip/filters/bcj2.rb +93 -0
  297. data/lib/omnizip/filters/bcj_arm.rb +174 -0
  298. data/lib/omnizip/filters/bcj_arm64.rb +242 -0
  299. data/lib/omnizip/filters/bcj_ia64.rb +194 -0
  300. data/lib/omnizip/filters/bcj_ppc.rb +188 -0
  301. data/lib/omnizip/filters/bcj_sparc.rb +174 -0
  302. data/lib/omnizip/filters/bcj_x86.rb +191 -0
  303. data/lib/omnizip/filters/delta.rb +195 -0
  304. data/lib/omnizip/filters/xz_delta.rb +258 -0
  305. data/lib/omnizip/filters.rb +20 -0
  306. data/lib/omnizip/format_detector.rb +166 -0
  307. data/lib/omnizip/formats/.keep +0 -0
  308. data/lib/omnizip/formats/bzip2_file.rb +159 -0
  309. data/lib/omnizip/formats/cpio/bounded_io.rb +66 -0
  310. data/lib/omnizip/formats/cpio/constants.rb +55 -0
  311. data/lib/omnizip/formats/cpio/entry.rb +389 -0
  312. data/lib/omnizip/formats/cpio/reader.rb +194 -0
  313. data/lib/omnizip/formats/cpio/writer.rb +232 -0
  314. data/lib/omnizip/formats/cpio.rb +132 -0
  315. data/lib/omnizip/formats/format_spec_loader.rb +228 -0
  316. data/lib/omnizip/formats/gzip.rb +236 -0
  317. data/lib/omnizip/formats/iso/directory_builder.rb +321 -0
  318. data/lib/omnizip/formats/iso/directory_record.rb +162 -0
  319. data/lib/omnizip/formats/iso/joliet.rb +204 -0
  320. data/lib/omnizip/formats/iso/path_table.rb +125 -0
  321. data/lib/omnizip/formats/iso/reader.rb +194 -0
  322. data/lib/omnizip/formats/iso/rock_ridge.rb +349 -0
  323. data/lib/omnizip/formats/iso/volume_builder.rb +319 -0
  324. data/lib/omnizip/formats/iso/volume_descriptor.rb +168 -0
  325. data/lib/omnizip/formats/iso/writer.rb +543 -0
  326. data/lib/omnizip/formats/iso.rb +133 -0
  327. data/lib/omnizip/formats/lzip.rb +161 -0
  328. data/lib/omnizip/formats/lzma_alone.rb +149 -0
  329. data/lib/omnizip/formats/msi/cab_extractor.rb +181 -0
  330. data/lib/omnizip/formats/msi/constants.rb +157 -0
  331. data/lib/omnizip/formats/msi/directory_resolver.rb +188 -0
  332. data/lib/omnizip/formats/msi/entry.rb +134 -0
  333. data/lib/omnizip/formats/msi/reader.rb +301 -0
  334. data/lib/omnizip/formats/msi/string_pool.rb +246 -0
  335. data/lib/omnizip/formats/msi/table_parser.rb +244 -0
  336. data/lib/omnizip/formats/msi.rb +73 -0
  337. data/lib/omnizip/formats/ole/allocation_table.rb +263 -0
  338. data/lib/omnizip/formats/ole/constants.rb +61 -0
  339. data/lib/omnizip/formats/ole/dirent.rb +439 -0
  340. data/lib/omnizip/formats/ole/header.rb +199 -0
  341. data/lib/omnizip/formats/ole/ranges_io.rb +347 -0
  342. data/lib/omnizip/formats/ole/storage.rb +482 -0
  343. data/lib/omnizip/formats/ole/types/variant.rb +338 -0
  344. data/lib/omnizip/formats/ole.rb +143 -0
  345. data/lib/omnizip/formats/rar/archive_repairer.rb +240 -0
  346. data/lib/omnizip/formats/rar/archive_verifier.rb +192 -0
  347. data/lib/omnizip/formats/rar/block_parser.rb +282 -0
  348. data/lib/omnizip/formats/rar/compression/bit_stream.rb +180 -0
  349. data/lib/omnizip/formats/rar/compression/dispatcher.rb +210 -0
  350. data/lib/omnizip/formats/rar/compression/lz77_huffman/decoder.rb +212 -0
  351. data/lib/omnizip/formats/rar/compression/lz77_huffman/encoder.rb +154 -0
  352. data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_builder.rb +217 -0
  353. data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_coder.rb +189 -0
  354. data/lib/omnizip/formats/rar/compression/lz77_huffman/match_finder.rb +135 -0
  355. data/lib/omnizip/formats/rar/compression/lz77_huffman/sliding_window.rb +165 -0
  356. data/lib/omnizip/formats/rar/compression/lz77_huffman.rb +25 -0
  357. data/lib/omnizip/formats/rar/compression/ppmd/context.rb +103 -0
  358. data/lib/omnizip/formats/rar/compression/ppmd/decoder.rb +238 -0
  359. data/lib/omnizip/formats/rar/compression/ppmd/encoder.rb +250 -0
  360. data/lib/omnizip/formats/rar/compression/ppmd.rb +16 -0
  361. data/lib/omnizip/formats/rar/compression.rb +17 -0
  362. data/lib/omnizip/formats/rar/compression_method_registry.rb +106 -0
  363. data/lib/omnizip/formats/rar/constants.rb +88 -0
  364. data/lib/omnizip/formats/rar/decompressor.rb +316 -0
  365. data/lib/omnizip/formats/rar/external_writer.rb +311 -0
  366. data/lib/omnizip/formats/rar/header.rb +209 -0
  367. data/lib/omnizip/formats/rar/license_validator.rb +111 -0
  368. data/lib/omnizip/formats/rar/models/rar_archive.rb +77 -0
  369. data/lib/omnizip/formats/rar/models/rar_entry.rb +65 -0
  370. data/lib/omnizip/formats/rar/models/rar_volume.rb +56 -0
  371. data/lib/omnizip/formats/rar/models.rb +14 -0
  372. data/lib/omnizip/formats/rar/parity_handler.rb +299 -0
  373. data/lib/omnizip/formats/rar/rar5/compression/lzma.rb +200 -0
  374. data/lib/omnizip/formats/rar/rar5/compression/lzss.rb +584 -0
  375. data/lib/omnizip/formats/rar/rar5/compression/store.rb +60 -0
  376. data/lib/omnizip/formats/rar/rar5/crc32.rb +39 -0
  377. data/lib/omnizip/formats/rar/rar5/encryption/aes256_cbc.rb +96 -0
  378. data/lib/omnizip/formats/rar/rar5/encryption/encryption_header.rb +114 -0
  379. data/lib/omnizip/formats/rar/rar5/encryption/encryption_manager.rb +162 -0
  380. data/lib/omnizip/formats/rar/rar5/encryption/key_derivation.rb +97 -0
  381. data/lib/omnizip/formats/rar/rar5/header.rb +208 -0
  382. data/lib/omnizip/formats/rar/rar5/models/encryption_options.rb +74 -0
  383. data/lib/omnizip/formats/rar/rar5/models/recovery_options.rb +63 -0
  384. data/lib/omnizip/formats/rar/rar5/models/solid_options.rb +63 -0
  385. data/lib/omnizip/formats/rar/rar5/models/volume_options.rb +74 -0
  386. data/lib/omnizip/formats/rar/rar5/multi_volume/ARCHITECTURE.md +290 -0
  387. data/lib/omnizip/formats/rar/rar5/multi_volume/volume_manager.rb +260 -0
  388. data/lib/omnizip/formats/rar/rar5/multi_volume/volume_splitter.rb +155 -0
  389. data/lib/omnizip/formats/rar/rar5/multi_volume/volume_writer.rb +176 -0
  390. data/lib/omnizip/formats/rar/rar5/solid/solid_encoder.rb +108 -0
  391. data/lib/omnizip/formats/rar/rar5/solid/solid_manager.rb +139 -0
  392. data/lib/omnizip/formats/rar/rar5/solid/solid_stream.rb +121 -0
  393. data/lib/omnizip/formats/rar/rar5/vint.rb +53 -0
  394. data/lib/omnizip/formats/rar/rar5/writer.rb +540 -0
  395. data/lib/omnizip/formats/rar/rar_format_base.rb +239 -0
  396. data/lib/omnizip/formats/rar/reader.rb +377 -0
  397. data/lib/omnizip/formats/rar/recovery_record.rb +245 -0
  398. data/lib/omnizip/formats/rar/volume_manager.rb +166 -0
  399. data/lib/omnizip/formats/rar/writer.rb +437 -0
  400. data/lib/omnizip/formats/rar.rb +193 -0
  401. data/lib/omnizip/formats/rar3/compressor.rb +71 -0
  402. data/lib/omnizip/formats/rar3/decompressor.rb +64 -0
  403. data/lib/omnizip/formats/rar3/reader.rb +107 -0
  404. data/lib/omnizip/formats/rar3/writer.rb +220 -0
  405. data/lib/omnizip/formats/rar3.rb +15 -0
  406. data/lib/omnizip/formats/rar5/compressor.rb +71 -0
  407. data/lib/omnizip/formats/rar5/decompressor.rb +64 -0
  408. data/lib/omnizip/formats/rar5/reader.rb +130 -0
  409. data/lib/omnizip/formats/rar5/writer.rb +65 -0
  410. data/lib/omnizip/formats/rar5.rb +15 -0
  411. data/lib/omnizip/formats/rpm/constants.rb +58 -0
  412. data/lib/omnizip/formats/rpm/entry.rb +106 -0
  413. data/lib/omnizip/formats/rpm/header.rb +106 -0
  414. data/lib/omnizip/formats/rpm/lead.rb +132 -0
  415. data/lib/omnizip/formats/rpm/tag.rb +228 -0
  416. data/lib/omnizip/formats/rpm/writer.rb +652 -0
  417. data/lib/omnizip/formats/rpm.rb +458 -0
  418. data/lib/omnizip/formats/seven_zip/bcj2_stream_decompressor.rb +274 -0
  419. data/lib/omnizip/formats/seven_zip/coder_chain.rb +169 -0
  420. data/lib/omnizip/formats/seven_zip/constants.rb +126 -0
  421. data/lib/omnizip/formats/seven_zip/encoded_header.rb +110 -0
  422. data/lib/omnizip/formats/seven_zip/encrypted_header.rb +139 -0
  423. data/lib/omnizip/formats/seven_zip/file_collector.rb +143 -0
  424. data/lib/omnizip/formats/seven_zip/header.rb +102 -0
  425. data/lib/omnizip/formats/seven_zip/header_encryptor.rb +132 -0
  426. data/lib/omnizip/formats/seven_zip/header_writer.rb +425 -0
  427. data/lib/omnizip/formats/seven_zip/models/coder_info.rb +30 -0
  428. data/lib/omnizip/formats/seven_zip/models/file_entry.rb +65 -0
  429. data/lib/omnizip/formats/seven_zip/models/folder.rb +67 -0
  430. data/lib/omnizip/formats/seven_zip/models/stream_info.rb +42 -0
  431. data/lib/omnizip/formats/seven_zip/models.rb +20 -0
  432. data/lib/omnizip/formats/seven_zip/parser.rb +671 -0
  433. data/lib/omnizip/formats/seven_zip/reader.rb +626 -0
  434. data/lib/omnizip/formats/seven_zip/split_archive_reader.rb +611 -0
  435. data/lib/omnizip/formats/seven_zip/split_archive_writer.rb +308 -0
  436. data/lib/omnizip/formats/seven_zip/stream_compressor.rb +151 -0
  437. data/lib/omnizip/formats/seven_zip/stream_decompressor.rb +166 -0
  438. data/lib/omnizip/formats/seven_zip/writer.rb +801 -0
  439. data/lib/omnizip/formats/seven_zip.rb +179 -0
  440. data/lib/omnizip/formats/tar/constants.rb +73 -0
  441. data/lib/omnizip/formats/tar/entry.rb +98 -0
  442. data/lib/omnizip/formats/tar/header.rb +206 -0
  443. data/lib/omnizip/formats/tar/reader.rb +119 -0
  444. data/lib/omnizip/formats/tar/writer.rb +212 -0
  445. data/lib/omnizip/formats/tar.rb +74 -0
  446. data/lib/omnizip/formats/xar/constants.rb +119 -0
  447. data/lib/omnizip/formats/xar/entry.rb +268 -0
  448. data/lib/omnizip/formats/xar/header.rb +223 -0
  449. data/lib/omnizip/formats/xar/reader.rb +400 -0
  450. data/lib/omnizip/formats/xar/toc.rb +570 -0
  451. data/lib/omnizip/formats/xar/writer.rb +461 -0
  452. data/lib/omnizip/formats/xar.rb +145 -0
  453. data/lib/omnizip/formats/xz/reader.rb +121 -0
  454. data/lib/omnizip/formats/xz/writer.rb +416 -0
  455. data/lib/omnizip/formats/xz.rb +210 -0
  456. data/lib/omnizip/formats/xz_const.rb +49 -0
  457. data/lib/omnizip/formats/xz_impl/block_decoder.rb +761 -0
  458. data/lib/omnizip/formats/xz_impl/block_encoder.rb +304 -0
  459. data/lib/omnizip/formats/xz_impl/block_header.rb +210 -0
  460. data/lib/omnizip/formats/xz_impl/block_header_parser.rb +182 -0
  461. data/lib/omnizip/formats/xz_impl/index_decoder.rb +174 -0
  462. data/lib/omnizip/formats/xz_impl/index_encoder.rb +120 -0
  463. data/lib/omnizip/formats/xz_impl/stream_decoder.rb +470 -0
  464. data/lib/omnizip/formats/xz_impl/stream_encoder.rb +95 -0
  465. data/lib/omnizip/formats/xz_impl/stream_footer.rb +79 -0
  466. data/lib/omnizip/formats/xz_impl/stream_footer_parser.rb +115 -0
  467. data/lib/omnizip/formats/xz_impl/stream_header.rb +53 -0
  468. data/lib/omnizip/formats/xz_impl/stream_header_parser.rb +106 -0
  469. data/lib/omnizip/formats/xz_impl/vli.rb +128 -0
  470. data/lib/omnizip/formats/xz_impl.rb +52 -0
  471. data/lib/omnizip/formats/zip/central_directory_header.rb +223 -0
  472. data/lib/omnizip/formats/zip/constants.rb +69 -0
  473. data/lib/omnizip/formats/zip/end_of_central_directory.rb +132 -0
  474. data/lib/omnizip/formats/zip/local_file_header.rb +136 -0
  475. data/lib/omnizip/formats/zip/reader.rb +376 -0
  476. data/lib/omnizip/formats/zip/unix_extra_field.rb +153 -0
  477. data/lib/omnizip/formats/zip/writer.rb +489 -0
  478. data/lib/omnizip/formats/zip/zip64_end_of_central_directory.rb +102 -0
  479. data/lib/omnizip/formats/zip/zip64_end_of_central_directory_locator.rb +64 -0
  480. data/lib/omnizip/formats/zip/zip64_extra_field.rb +112 -0
  481. data/lib/omnizip/formats/zip.rb +50 -0
  482. data/lib/omnizip/formats.rb +29 -0
  483. data/lib/omnizip/implementations/base/lzma2_decoder_base.rb +75 -0
  484. data/lib/omnizip/implementations/base/lzma2_encoder_base.rb +128 -0
  485. data/lib/omnizip/implementations/base/lzma_decoder_base.rb +83 -0
  486. data/lib/omnizip/implementations/base/lzma_encoder_base.rb +108 -0
  487. data/lib/omnizip/implementations/base/state_machine_base.rb +182 -0
  488. data/lib/omnizip/implementations/base.rb +19 -0
  489. data/lib/omnizip/implementations/rust/archive.rb +93 -0
  490. data/lib/omnizip/implementations/rust/library.rb +221 -0
  491. data/lib/omnizip/implementations/rust.rb +26 -0
  492. data/lib/omnizip/implementations/seven_zip/lzma/decoder.rb +428 -0
  493. data/lib/omnizip/implementations/seven_zip/lzma/encoder.rb +456 -0
  494. data/lib/omnizip/implementations/seven_zip/lzma/match_finder.rb +285 -0
  495. data/lib/omnizip/implementations/seven_zip/lzma/range_decoder.rb +197 -0
  496. data/lib/omnizip/implementations/seven_zip/lzma/range_encoder.rb +194 -0
  497. data/lib/omnizip/implementations/seven_zip/lzma/state_machine.rb +139 -0
  498. data/lib/omnizip/implementations/seven_zip/lzma.rb +21 -0
  499. data/lib/omnizip/implementations/seven_zip/lzma2/encoder.rb +56 -0
  500. data/lib/omnizip/implementations/seven_zip/lzma2.rb +12 -0
  501. data/lib/omnizip/implementations/seven_zip.rb +11 -0
  502. data/lib/omnizip/implementations/xz_utils/lzma2/decoder.rb +547 -0
  503. data/lib/omnizip/implementations/xz_utils/lzma2/encoder.rb +748 -0
  504. data/lib/omnizip/implementations/xz_utils/lzma2.rb +13 -0
  505. data/lib/omnizip/implementations/xz_utils.rb +10 -0
  506. data/lib/omnizip/implementations.rb +25 -0
  507. data/lib/omnizip/io/buffered_input.rb +147 -0
  508. data/lib/omnizip/io/buffered_output.rb +106 -0
  509. data/lib/omnizip/io/source.rb +143 -0
  510. data/lib/omnizip/io/stream_manager.rb +117 -0
  511. data/lib/omnizip/io.rb +15 -0
  512. data/lib/omnizip/link_handler/hard_link.rb +79 -0
  513. data/lib/omnizip/link_handler/symbolic_link.rb +74 -0
  514. data/lib/omnizip/link_handler.rb +129 -0
  515. data/lib/omnizip/metadata/archive_metadata.rb +114 -0
  516. data/lib/omnizip/metadata/entry_metadata.rb +153 -0
  517. data/lib/omnizip/metadata/metadata_editor.rb +169 -0
  518. data/lib/omnizip/metadata/metadata_registry.rb +71 -0
  519. data/lib/omnizip/metadata/metadata_validator.rb +101 -0
  520. data/lib/omnizip/metadata.rb +58 -0
  521. data/lib/omnizip/models/.keep +0 -0
  522. data/lib/omnizip/models/algorithm_metadata.rb +41 -0
  523. data/lib/omnizip/models/attribute_apply.rb +40 -0
  524. data/lib/omnizip/models/compression_options.rb +53 -0
  525. data/lib/omnizip/models/conversion_options.rb +79 -0
  526. data/lib/omnizip/models/conversion_result.rb +141 -0
  527. data/lib/omnizip/models/eta_result.rb +45 -0
  528. data/lib/omnizip/models/extraction_rule.rb +115 -0
  529. data/lib/omnizip/models/filter_chain.rb +142 -0
  530. data/lib/omnizip/models/filter_config.rb +148 -0
  531. data/lib/omnizip/models/match_result.rb +141 -0
  532. data/lib/omnizip/models/optimization_suggestion.rb +95 -0
  533. data/lib/omnizip/models/parallel_options.rb +116 -0
  534. data/lib/omnizip/models/performance_result.rb +85 -0
  535. data/lib/omnizip/models/profile_report.rb +116 -0
  536. data/lib/omnizip/models/progress_options.rb +39 -0
  537. data/lib/omnizip/models/split_options.rb +116 -0
  538. data/lib/omnizip/optimization_registry.rb +45 -0
  539. data/lib/omnizip/parallel/engine.rb +52 -0
  540. data/lib/omnizip/parallel/job_queue.rb +209 -0
  541. data/lib/omnizip/parallel/job_scheduler.rb +225 -0
  542. data/lib/omnizip/parallel/parallel_compressor.rb +326 -0
  543. data/lib/omnizip/parallel/parallel_extractor.rb +238 -0
  544. data/lib/omnizip/parallel/thread_pool.rb +60 -0
  545. data/lib/omnizip/parallel/worker_pool.rb +227 -0
  546. data/lib/omnizip/parallel.rb +156 -0
  547. data/lib/omnizip/parity/chunked_block_processor.rb +194 -0
  548. data/lib/omnizip/parity/galois16.rb +145 -0
  549. data/lib/omnizip/parity/models/creator_packet.rb +71 -0
  550. data/lib/omnizip/parity/models/file_description_packet.rb +131 -0
  551. data/lib/omnizip/parity/models/ifsc_packet.rb +111 -0
  552. data/lib/omnizip/parity/models/main_packet.rb +126 -0
  553. data/lib/omnizip/parity/models/packet.rb +156 -0
  554. data/lib/omnizip/parity/models/packet_registry.rb +102 -0
  555. data/lib/omnizip/parity/models/recovery_slice_packet.rb +76 -0
  556. data/lib/omnizip/parity/models.rb +27 -0
  557. data/lib/omnizip/parity/par2_creator.rb +496 -0
  558. data/lib/omnizip/parity/par2_repairer.rb +409 -0
  559. data/lib/omnizip/parity/par2_verifier.rb +373 -0
  560. data/lib/omnizip/parity/par2cmdline_algorithm.rb +108 -0
  561. data/lib/omnizip/parity/par2cmdline_coefficients.rb +78 -0
  562. data/lib/omnizip/parity/reed_solomon_decoder.rb +263 -0
  563. data/lib/omnizip/parity/reed_solomon_encoder.rb +108 -0
  564. data/lib/omnizip/parity/reed_solomon_matrix.rb +339 -0
  565. data/lib/omnizip/parity.rb +207 -0
  566. data/lib/omnizip/password/encryption_registry.rb +26 -0
  567. data/lib/omnizip/password/encryption_strategy.rb +96 -0
  568. data/lib/omnizip/password/password_validator.rb +129 -0
  569. data/lib/omnizip/password/winzip_aes_strategy.rb +190 -0
  570. data/lib/omnizip/password/zip_crypto_strategy.rb +135 -0
  571. data/lib/omnizip/password.rb +88 -0
  572. data/lib/omnizip/pipe/stream_compressor.rb +124 -0
  573. data/lib/omnizip/pipe/stream_decompressor.rb +173 -0
  574. data/lib/omnizip/pipe.rb +120 -0
  575. data/lib/omnizip/platform/ntfs_streams.rb +200 -0
  576. data/lib/omnizip/platform.rb +189 -0
  577. data/lib/omnizip/profile/archive_profile.rb +36 -0
  578. data/lib/omnizip/profile/balanced_profile.rb +31 -0
  579. data/lib/omnizip/profile/binary_profile.rb +33 -0
  580. data/lib/omnizip/profile/compression_profile.rb +157 -0
  581. data/lib/omnizip/profile/custom_profile.rb +155 -0
  582. data/lib/omnizip/profile/fast_profile.rb +31 -0
  583. data/lib/omnizip/profile/maximum_profile.rb +31 -0
  584. data/lib/omnizip/profile/profile_detector.rb +108 -0
  585. data/lib/omnizip/profile/profile_registry.rb +160 -0
  586. data/lib/omnizip/profile/text_profile.rb +33 -0
  587. data/lib/omnizip/profile.rb +261 -0
  588. data/lib/omnizip/profiler/memory_profiler.rb +66 -0
  589. data/lib/omnizip/profiler/method_profiler.rb +49 -0
  590. data/lib/omnizip/profiler/report_generator.rb +158 -0
  591. data/lib/omnizip/profiler.rb +192 -0
  592. data/lib/omnizip/progress/callback_reporter.rb +34 -0
  593. data/lib/omnizip/progress/console_reporter.rb +59 -0
  594. data/lib/omnizip/progress/log_reporter.rb +89 -0
  595. data/lib/omnizip/progress/operation_progress.rb +118 -0
  596. data/lib/omnizip/progress/progress_bar.rb +156 -0
  597. data/lib/omnizip/progress/progress_reporter.rb +40 -0
  598. data/lib/omnizip/progress/progress_tracker.rb +215 -0
  599. data/lib/omnizip/progress/silent_reporter.rb +22 -0
  600. data/lib/omnizip/progress.rb +131 -0
  601. data/lib/omnizip/registry.rb +111 -0
  602. data/lib/omnizip/rubyzip_compat.rb +61 -0
  603. data/lib/omnizip/temp/safe_extract.rb +124 -0
  604. data/lib/omnizip/temp/temp_file.rb +123 -0
  605. data/lib/omnizip/temp/temp_file_pool.rb +109 -0
  606. data/lib/omnizip/temp.rb +184 -0
  607. data/lib/omnizip/version.rb +5 -0
  608. data/lib/omnizip/zip/entry.rb +160 -0
  609. data/lib/omnizip/zip/file.rb +485 -0
  610. data/lib/omnizip/zip/input_stream.rb +270 -0
  611. data/lib/omnizip/zip/output_stream.rb +320 -0
  612. data/lib/omnizip/zip.rb +23 -0
  613. data/lib/omnizip.rb +157 -0
  614. data/lib/tasks/msi_test_files.rake +66 -0
  615. data/lib/tasks/platform_gems.rake +147 -0
  616. data/lib/tasks/rust_backend.rake +48 -0
  617. data/readme-docs/advanced-features.adoc +514 -0
  618. data/readme-docs/api-usage.adoc +445 -0
  619. data/readme-docs/architecture.adoc +450 -0
  620. data/readme-docs/archive-formats.adoc +479 -0
  621. data/readme-docs/cli-usage.adoc +222 -0
  622. data/readme-docs/compression-algorithms.adoc +446 -0
  623. data/readme-docs/compression-profiles.adoc +247 -0
  624. data/readme-docs/encryption-checksums.adoc +328 -0
  625. data/readme-docs/format-converter.adoc +316 -0
  626. data/readme-docs/installation.adoc +228 -0
  627. data/readme-docs/par2-archives.adoc +608 -0
  628. data/readme-docs/performance-profiler.adoc +389 -0
  629. data/readme-docs/preprocessing-filters.adoc +280 -0
  630. data/vendor/libomnizip_ffi.so +0 -0
  631. data/xz-file-format-1.2.1.txt +1174 -0
  632. metadata +768 -0
@@ -0,0 +1,339 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Parity
5
+ # Reed-Solomon matrix for incremental chunk processing
6
+ #
7
+ # This class computes the RS matrix coefficients ONCE using Gaussian
8
+ # elimination, then provides methods to apply those coefficients
9
+ # incrementally to data chunks.
10
+ #
11
+ # Based on par2cmdline's approach (reedsolomon.h, par2repairer.cpp)
12
+ class ReedSolomonMatrix
13
+ # @return [Array<Integer>] Indices of present input blocks
14
+ attr_reader :present_indices
15
+
16
+ # @return [Array<Integer>] Indices of missing input blocks
17
+ attr_reader :missing_indices
18
+
19
+ # @return [Array<Integer>] All available recovery exponents
20
+ attr_reader :recovery_exponents
21
+
22
+ # @return [Array<Integer>] Recovery exponents actually used (first num_missing)
23
+ attr_reader :used_recovery_exponents
24
+
25
+ # @return [Integer] Total number of input blocks
26
+ attr_reader :total_inputs
27
+
28
+ # @return [Integer] Block size in bytes
29
+ attr_reader :block_size
30
+
31
+ # @return [Array<Array<Integer>>] Solved matrix coefficients (num_missing x num_missing)
32
+ attr_reader :matrix
33
+
34
+ # @return [Array<Integer>] Selected bases for Galois field
35
+ attr_reader :bases
36
+
37
+ # Initialize matrix
38
+ #
39
+ # @param present_indices [Array<Integer>] Indices of available data blocks
40
+ # @param missing_indices [Array<Integer>] Indices of blocks to recover
41
+ # @param recovery_exponents [Array<Integer>] Exponents of recovery blocks to use
42
+ # @param total_inputs [Integer] Total number of input blocks (present + missing)
43
+ # @param block_size [Integer] Block size in bytes
44
+ def initialize(present_indices, missing_indices, recovery_exponents,
45
+ total_inputs, block_size)
46
+ @present_indices = present_indices.sort
47
+ @missing_indices = missing_indices.sort
48
+ @recovery_exponents = recovery_exponents.sort
49
+ @total_inputs = total_inputs
50
+ @block_size = block_size
51
+ @matrix = nil # Computed by compute!
52
+ @bases = nil # Computed by compute!
53
+ @used_recovery_exponents = nil # Computed by compute!
54
+ end
55
+
56
+ # Compute matrix coefficients using Gaussian elimination
57
+ #
58
+ # CORRECT FORMULATION:
59
+ # We solve: A * x = b
60
+ # where:
61
+ # - A[i,j] = base[missing[j]]^exponent[i] (num_missing x num_missing)
62
+ # - x[j] = missing_block[j] (what we solve for)
63
+ # - b[i] = recovery[i] - sum(present[k] * base[present[k]]^exponent[i])
64
+ #
65
+ # This method computes A^-1, so we can later compute:
66
+ # x = A^-1 * b
67
+ #
68
+ # @return [void]
69
+ def compute!
70
+ @bases = Par2cmdlineAlgorithm.compute_bases(total_inputs)
71
+
72
+ num_missing = missing_indices.size
73
+
74
+ # Select which recovery exponents to use (first num_missing)
75
+ @used_recovery_exponents = recovery_exponents.first(num_missing)
76
+
77
+ # Build A matrix: A[i,j] = base[missing[j]]^exponent[i]
78
+ # This is num_missing x num_missing (SQUARE)
79
+ a_matrix = Array.new(num_missing) { Array.new(num_missing, 0) }
80
+
81
+ @used_recovery_exponents.each_with_index do |exponent, row|
82
+ missing_indices.each_with_index do |idx, col|
83
+ a_matrix[row][col] = Galois16.power(@bases[idx], exponent)
84
+ end
85
+ end
86
+
87
+ # Invert A matrix using Gaussian elimination
88
+ # Create augmented matrix [A | I]
89
+ identity = Array.new(num_missing) do |i|
90
+ Array.new(num_missing) do |j|
91
+ i == j ? 1 : 0
92
+ end
93
+ end
94
+
95
+ gaussian_elimination!(a_matrix, identity)
96
+
97
+ # Store inverted matrix (now in identity position)
98
+ # IMPORTANT: Transpose it so rows=missing_indices, cols=recovery_indices
99
+ # This allows direct indexing: matrix[output_idx][recovery_idx]
100
+ @matrix = identity.transpose
101
+ end
102
+
103
+ # Get matrix coefficient for computing missing blocks
104
+ #
105
+ # This returns the coefficient from A^-1 matrix that tells us how much
106
+ # each recovery block contributes to each missing block.
107
+ #
108
+ # After transposition, matrix structure is:
109
+ # - matrix[recovery_idx][output_idx] (rows=recovery, cols=missing)
110
+ #
111
+ # For x = A^-1 * b:
112
+ # x[output_idx] = sum over recovery_idx of A^-1[output_idx][recovery_idx] * b[recovery_idx]
113
+ #
114
+ # Due to transpose, we access as: matrix[recovery_idx][output_idx]
115
+ #
116
+ # @param output_idx [Integer] Output block index (0..missing_count-1)
117
+ # @param recovery_idx [Integer] Recovery block index (0..recovery_count-1)
118
+ # @return [Integer] Galois field coefficient
119
+ def coefficient(output_idx, recovery_idx)
120
+ raise Omnizip::Error, "Matrix not computed - call compute! first" unless @matrix
121
+
122
+ # After transpose, indices are swapped: @matrix[recovery_idx][output_idx]
123
+ @matrix[recovery_idx][output_idx]
124
+ end
125
+
126
+ # Get coefficient for present block contribution to b vector
127
+ #
128
+ # Returns how much a present block contributes when building b vector.
129
+ # This is: -base[present_idx]^exponent[recovery_idx]
130
+ #
131
+ # @param present_idx [Integer] Index of present data block
132
+ # @param recovery_exponent [Integer] Recovery block exponent
133
+ # @return [Integer] Galois field coefficient
134
+ def present_contribution_coefficient(present_idx, recovery_exponent)
135
+ Galois16.power(@bases[present_idx], recovery_exponent)
136
+ end
137
+
138
+ # Process a chunk of data: output_chunk ^= input_chunk * factor
139
+ #
140
+ # This is called thousands of times during repair to incrementally
141
+ # build up each recovered block chunk by chunk.
142
+ #
143
+ # @param factor [Integer] Galois field multiplier (from matrix)
144
+ # @param input_chunk [String] Input chunk data
145
+ # @param output_block [String] Full output block (modified in place)
146
+ # @param chunk_size [Integer] Chunk size in bytes (must be even)
147
+ # @param output_offset [Integer] Offset within output block where to write
148
+ def process_chunk(factor, input_chunk, output_block, chunk_size,
149
+ output_offset: 0)
150
+ return if factor.zero? # Optimization
151
+
152
+ num_words = chunk_size / 2
153
+
154
+ num_words.times do |i|
155
+ input_offset = i * 2
156
+ block_offset = output_offset + (i * 2)
157
+
158
+ # Read 16-bit words (little-endian)
159
+ input_word = input_chunk.getbyte(input_offset) |
160
+ (input_chunk.getbyte(input_offset + 1) << 8)
161
+
162
+ output_word = output_block.getbyte(block_offset) |
163
+ (output_block.getbyte(block_offset + 1) << 8)
164
+
165
+ # Galois multiplication and addition (XOR)
166
+ result = Galois16.add(output_word,
167
+ Galois16.multiply(input_word, factor))
168
+
169
+ # Write back as bytes (little-endian)
170
+ output_block.setbyte(block_offset, result & 0xFF)
171
+ output_block.setbyte(block_offset + 1, (result >> 8) & 0xFF)
172
+ end
173
+ end
174
+
175
+ # Get number of recovery blocks used
176
+ #
177
+ # @return [Integer] Recovery count
178
+ def recovery_count
179
+ recovery_exponents.size
180
+ end
181
+
182
+ # Get number of output blocks (missing)
183
+ #
184
+ # @return [Integer] Output count
185
+ def output_count
186
+ missing_indices.size
187
+ end
188
+
189
+ private
190
+
191
+ # Perform Gaussian elimination to invert matrix
192
+ #
193
+ # Transforms [A | I] into [I | A^-1]
194
+ #
195
+ # @param left_matrix [Array<Array<Integer>>] Matrix to invert (modified)
196
+ # @param right_matrix [Array<Array<Integer>>] Identity matrix (becomes inverse)
197
+ def gaussian_elimination!(left_matrix, right_matrix)
198
+ num_rows = left_matrix.size
199
+ num_cols = left_matrix[0].size
200
+
201
+ num_rows.times do |pivot_row|
202
+ pivot = left_matrix[pivot_row][pivot_row]
203
+ raise Omnizip::Error, "Singular matrix at row #{pivot_row}" if pivot.zero?
204
+
205
+ # Scale pivot row to make pivot = 1
206
+ unless pivot == 1
207
+ num_cols.times do |col|
208
+ next if left_matrix[pivot_row][col].zero?
209
+
210
+ left_matrix[pivot_row][col] =
211
+ Galois16.divide(left_matrix[pivot_row][col], pivot)
212
+ end
213
+
214
+ num_cols.times do |col|
215
+ next if right_matrix[pivot_row][col].zero?
216
+
217
+ right_matrix[pivot_row][col] =
218
+ Galois16.divide(right_matrix[pivot_row][col], pivot)
219
+ end
220
+ end
221
+
222
+ # Eliminate column in all other rows
223
+ num_rows.times do |row|
224
+ next if row == pivot_row
225
+
226
+ scale = left_matrix[row][pivot_row]
227
+ next if scale.zero?
228
+
229
+ if scale == 1
230
+ num_cols.times do |col|
231
+ next if left_matrix[pivot_row][col].zero?
232
+
233
+ left_matrix[row][col] = Galois16.add(
234
+ left_matrix[row][col],
235
+ left_matrix[pivot_row][col],
236
+ )
237
+ end
238
+
239
+ num_cols.times do |col|
240
+ next if right_matrix[pivot_row][col].zero?
241
+
242
+ right_matrix[row][col] = Galois16.add(
243
+ right_matrix[row][col],
244
+ right_matrix[pivot_row][col],
245
+ )
246
+ end
247
+ else
248
+ num_cols.times do |col|
249
+ next if left_matrix[pivot_row][col].zero?
250
+
251
+ scaled = Galois16.multiply(left_matrix[pivot_row][col], scale)
252
+ left_matrix[row][col] =
253
+ Galois16.add(left_matrix[row][col], scaled)
254
+ end
255
+
256
+ num_cols.times do |col|
257
+ next if right_matrix[pivot_row][col].zero?
258
+
259
+ scaled = Galois16.multiply(right_matrix[pivot_row][col], scale)
260
+ right_matrix[row][col] =
261
+ Galois16.add(right_matrix[row][col], scaled)
262
+ end
263
+ end
264
+ end
265
+ end
266
+ end
267
+
268
+ # Verify that A * A^-1 = Identity
269
+ # @param a_original [Array<Array<Integer>>] Original A matrix
270
+ # @param a_inv [Array<Array<Integer>>] Computed A^-1 matrix
271
+ # @return [Boolean] true if verification passes
272
+ def verify_matrix_inversion(a_original, a_inv)
273
+ n = a_original.size
274
+
275
+ # Compute A * A^-1
276
+ result = Array.new(n) { Array.new(n, 0) }
277
+ n.times do |i|
278
+ n.times do |j|
279
+ sum = 0
280
+ n.times do |k|
281
+ product = Galois16.multiply(a_original[i][k], a_inv[k][j])
282
+ sum = Galois16.add(sum, product)
283
+ end
284
+ result[i][j] = sum
285
+ end
286
+ end
287
+
288
+ # Check if result is identity
289
+ n.times do |i|
290
+ n.times do |j|
291
+ expected = i == j ? 1 : 0
292
+ return false if result[i][j] != expected
293
+ end
294
+ end
295
+
296
+ true
297
+ end
298
+ end
299
+ end
300
+
301
+ # Verify that A * A^-1 = Identity
302
+ #
303
+ # @param a_original [Array<Array<Integer>>] Original A matrix
304
+ # @param a_inv [Array<Array<Integer>>] Computed A^-1 matrix
305
+ # @return [Boolean] true if verification passes
306
+ def self.verify_matrix_inversion(a_original, a_inv)
307
+ n = a_original.size
308
+
309
+ # Compute A * A^-1
310
+ result = Array.new(n) { Array.new(n, 0) }
311
+ n.times do |i|
312
+ n.times do |j|
313
+ sum = 0
314
+ n.times do |k|
315
+ product = Galois16.multiply(a_original[i][k], a_inv[k][j])
316
+ sum = Galois16.add(sum, product)
317
+ end
318
+ result[i][j] = sum
319
+ end
320
+ end
321
+
322
+ # Check if result is identity
323
+ n.times do |i|
324
+ n.times do |j|
325
+ expected = i == j ? 1 : 0
326
+ if result[i][j] != expected
327
+ warn "MATRIX VERIFICATION FAILED!"
328
+ warn " A * A^-1 at [#{i},#{j}] = 0x#{format('%04X',
329
+ result[i][j])} (expected #{expected})"
330
+ warn " This means Gaussian elimination produced wrong inverse!"
331
+ return false
332
+ end
333
+ end
334
+ end
335
+
336
+ warn "Matrix verification: A * A^-1 = I ✓"
337
+ true
338
+ end
339
+ end
@@ -0,0 +1,207 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ # PAR2 parity archive support
5
+ #
6
+ # Provides creation, verification, and repair of PAR2 parity files
7
+ # for protecting archives and data files against corruption.
8
+ #
9
+ # PAR2 uses Reed-Solomon error correction codes to create recovery
10
+ # data that can reconstruct missing or corrupted blocks.
11
+ #
12
+ # @example Create PAR2 protection
13
+ # Omnizip::Parity.create('archive.zip', redundancy: 10)
14
+ #
15
+ # @example Verify and repair
16
+ # result = Omnizip::Parity.verify('archive.par2')
17
+ # Omnizip::Parity.repair('archive.par2') if result.repairable?
18
+ module Parity
19
+ # Nested classes - autoloaded
20
+ autoload :Galois16, "omnizip/parity/galois16"
21
+ autoload :Par2cmdlineAlgorithm, "omnizip/parity/par2cmdline_algorithm"
22
+ autoload :Par2cmdlineCoefficients, "omnizip/parity/par2cmdline_coefficients"
23
+ autoload :ReedSolomonMatrix, "omnizip/parity/reed_solomon_matrix"
24
+ autoload :ReedSolomonEncoder, "omnizip/parity/reed_solomon_encoder"
25
+ autoload :ReedSolomonDecoder, "omnizip/parity/reed_solomon_decoder"
26
+ autoload :ChunkedBlockProcessor, "omnizip/parity/chunked_block_processor"
27
+ autoload :Par2Creator, "omnizip/parity/par2_creator"
28
+ autoload :Par2Verifier, "omnizip/parity/par2_verifier"
29
+ autoload :Par2Repairer, "omnizip/parity/par2_repairer"
30
+
31
+ # Models namespace
32
+ module Models
33
+ autoload :Packet, "omnizip/parity/models/packet"
34
+ autoload :PacketRegistry, "omnizip/parity/models/packet_registry"
35
+ autoload :MainPacket, "omnizip/parity/models/main_packet"
36
+ autoload :FileDescriptionPacket,
37
+ "omnizip/parity/models/file_description_packet"
38
+ autoload :IfscPacket, "omnizip/parity/models/ifsc_packet"
39
+ autoload :RecoverySlicePacket,
40
+ "omnizip/parity/models/recovery_slice_packet"
41
+ autoload :CreatorPacket, "omnizip/parity/models/creator_packet"
42
+ end
43
+ autoload :Models, "omnizip/parity/models"
44
+
45
+ class << self
46
+ # Create PAR2 recovery files for archive or files
47
+ #
48
+ # @param file_or_pattern [String] File path or glob pattern
49
+ # @param redundancy [Integer] Redundancy percentage (0-100)
50
+ # @param block_size [Integer] Block size in bytes
51
+ # @param output_dir [String, nil] Output directory for PAR2 files
52
+ # @param progress [Proc, nil] Progress callback
53
+ # @return [Array<String>] Created PAR2 file paths
54
+ #
55
+ # @example Create with 10% redundancy
56
+ # Omnizip::Parity.create('backup.7z', redundancy: 10)
57
+ #
58
+ # @example Create for multiple files
59
+ # Omnizip::Parity.create('data/*.dat', redundancy: 5)
60
+ #
61
+ # @example With progress tracking
62
+ # Omnizip::Parity.create('large.zip',
63
+ # redundancy: 10,
64
+ # progress: ->(pct, msg) { puts "#{pct}%: #{msg}" }
65
+ # )
66
+ def create(file_or_pattern, redundancy: 5, block_size: Par2Creator::DEFAULT_BLOCK_SIZE,
67
+ output_dir: nil, progress: nil)
68
+ # Try glob expansion first (handles both patterns and single files)
69
+ files = Dir.glob(file_or_pattern)
70
+
71
+ # If glob returns nothing, check if it's a single existing file
72
+ if files.empty? && File.exist?(file_or_pattern) && !File.directory?(file_or_pattern)
73
+ files = [file_or_pattern]
74
+ end
75
+
76
+ if files.empty?
77
+ raise ArgumentError,
78
+ "No files match pattern: #{file_or_pattern}"
79
+ end
80
+
81
+ # Create PAR2 creator
82
+ creator = Par2Creator.new(
83
+ redundancy: redundancy,
84
+ block_size: block_size,
85
+ progress: progress,
86
+ )
87
+
88
+ # Add all files
89
+ files.each { |file| creator.add_file(file) }
90
+
91
+ # Determine output base name
92
+ dir = output_dir || File.dirname(files.first)
93
+ base_name = if files.size == 1
94
+ # Use file's directory and base name without extension
95
+ File.join(dir, File.basename(files.first, ".*"))
96
+ else
97
+ # Use files' directory name for multiple files
98
+ File.join(dir,
99
+ File.basename(File.dirname(files.first)))
100
+ end
101
+
102
+ # Create PAR2 files
103
+ creator.create(base_name)
104
+ end
105
+
106
+ # Verify files using PAR2 recovery data
107
+ #
108
+ # @param par2_file [String] Path to .par2 index file
109
+ # @return [Par2Verifier::VerificationResult] Verification results
110
+ #
111
+ # @example Verify archive integrity
112
+ # result = Omnizip::Parity.verify('backup.par2')
113
+ # if result.all_ok?
114
+ # puts "All files intact"
115
+ # elsif result.repairable?
116
+ # puts "Damage detected but repairable"
117
+ # else
118
+ # puts "Damage cannot be repaired"
119
+ # end
120
+ def verify(par2_file)
121
+ verifier = Par2Verifier.new(par2_file)
122
+ verifier.verify
123
+ end
124
+
125
+ # Repair damaged files using PAR2 recovery data
126
+ #
127
+ # @param par2_file [String] Path to .par2 index file
128
+ # @param output_dir [String, nil] Output directory for repaired files
129
+ # @param progress [Proc, nil] Progress callback
130
+ # @return [Par2Repairer::RepairResult] Repair results
131
+ #
132
+ # @example Repair damaged archive
133
+ # result = Omnizip::Parity.repair('backup.par2')
134
+ # if result.success?
135
+ # puts "Successfully recovered #{result.recovered_files.join(', ')}"
136
+ # else
137
+ # puts "Repair failed: #{result.error_message}"
138
+ # end
139
+ def repair(par2_file, output_dir: nil, progress: nil)
140
+ repairer = Par2Repairer.new(par2_file, progress: progress)
141
+ repairer.repair(output_dir: output_dir)
142
+ end
143
+
144
+ # Quick check if PAR2 files exist for a file
145
+ #
146
+ # @param file_path [String] Path to protected file
147
+ # @return [Boolean] true if PAR2 files exist
148
+ #
149
+ # @example Check for protection
150
+ # if Omnizip::Parity.protected?('backup.zip')
151
+ # puts "File is protected by PAR2"
152
+ # end
153
+ def protected?(file_path)
154
+ base_name = File.basename(file_path, ".*")
155
+ dir_name = File.dirname(file_path)
156
+ par2_file = File.join(dir_name, "#{base_name}.par2")
157
+
158
+ File.exist?(par2_file)
159
+ end
160
+
161
+ # Get PAR2 protection information
162
+ #
163
+ # @param file_path [String] Path to protected file
164
+ # @return [Hash, nil] Protection information or nil if not protected
165
+ #
166
+ # @example Get protection info
167
+ # info = Omnizip::Parity.info('backup.zip')
168
+ # puts "Redundancy: #{info[:redundancy]}%"
169
+ # puts "Block size: #{info[:block_size]} bytes"
170
+ def info(file_path)
171
+ base_name = File.basename(file_path, ".*")
172
+ dir_name = File.dirname(file_path)
173
+ par2_file = File.join(dir_name, "#{base_name}.par2")
174
+
175
+ return nil unless File.exist?(par2_file)
176
+
177
+ verifier = Par2Verifier.new(par2_file)
178
+ verifier.parse_par2_file
179
+
180
+ total_blocks = verifier.calculate_total_blocks
181
+ recovery_blocks = verifier.recovery_blocks.size
182
+
183
+ {
184
+ par2_file: par2_file,
185
+ block_size: verifier.metadata[:block_size],
186
+ total_blocks: total_blocks,
187
+ file_count: verifier.metadata[:file_count] || verifier.file_list.size,
188
+ recovery_blocks: recovery_blocks,
189
+ redundancy: calculate_redundancy(total_blocks, recovery_blocks),
190
+ }
191
+ end
192
+
193
+ private
194
+
195
+ # Calculate redundancy percentage
196
+ #
197
+ # @param total_blocks [Integer] Total data blocks
198
+ # @param recovery_blocks [Integer] Recovery blocks
199
+ # @return [Float] Redundancy percentage
200
+ def calculate_redundancy(total_blocks, recovery_blocks)
201
+ return 0.0 if total_blocks.nil? || total_blocks.zero?
202
+
203
+ (recovery_blocks.to_f / total_blocks * 100).round(2)
204
+ end
205
+ end
206
+ end
207
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Password
5
+ class EncryptionRegistry < Omnizip::Registry
6
+ class << self
7
+ def not_found_error_class
8
+ Omnizip::UnknownEncryptionStrategyError
9
+ end
10
+
11
+ def label
12
+ "Encryption strategy"
13
+ end
14
+
15
+ def create(name, password, **options)
16
+ get(name).new(password, **options)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ Omnizip::Password::EncryptionRegistry.register(:traditional, Omnizip::Password::ZipCryptoStrategy)
24
+ Omnizip::Password::EncryptionRegistry.register(:zip_crypto, Omnizip::Password::ZipCryptoStrategy)
25
+ Omnizip::Password::EncryptionRegistry.register(:winzip_aes, Omnizip::Password::WinzipAesStrategy)
26
+ Omnizip::Password::EncryptionRegistry.register(:aes256, Omnizip::Password::WinzipAesStrategy)
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Password
5
+ # Base class for encryption strategies
6
+ # Defines the interface for encrypting/decrypting archive entries
7
+ class EncryptionStrategy
8
+ attr_reader :password
9
+
10
+ # Initialize encryption strategy
11
+ # @param password [String] Password to use
12
+ def initialize(password)
13
+ @password = password
14
+ validate_password
15
+ end
16
+
17
+ # Encrypt data
18
+ # @param data [String] Data to encrypt
19
+ # @return [String] Encrypted data
20
+ # @raise [NotImplementedError] Subclasses must implement
21
+ def encrypt(data)
22
+ raise NotImplementedError, "#{self.class} must implement #encrypt"
23
+ end
24
+
25
+ # Decrypt data
26
+ # @param data [String] Data to decrypt
27
+ # @return [String] Decrypted data
28
+ # @raise [NotImplementedError] Subclasses must implement
29
+ def decrypt(data)
30
+ raise NotImplementedError, "#{self.class} must implement #decrypt"
31
+ end
32
+
33
+ # Get encryption method ID for ZIP format
34
+ # @return [Integer] Compression method ID
35
+ # @raise [NotImplementedError] Subclasses must implement
36
+ def compression_method
37
+ raise NotImplementedError,
38
+ "#{self.class} must implement #compression_method"
39
+ end
40
+
41
+ # Get extra field data for ZIP header
42
+ # @return [String] Extra field data
43
+ def extra_field_data
44
+ ""
45
+ end
46
+
47
+ # Get encryption flags for ZIP header
48
+ # @return [Integer] Encryption flags
49
+ def encryption_flags
50
+ 0x0001 # Bit 0: encrypted
51
+ end
52
+
53
+ # Check if this strategy supports the given data
54
+ # @param data [String] Data to check
55
+ # @return [Boolean] True if supported
56
+ def supports?(_data)
57
+ true
58
+ end
59
+
60
+ # Get encryption method name
61
+ # @return [Symbol] Method name
62
+ def method_name
63
+ self.class.name.split("::").last
64
+ .gsub(/Strategy$/, "")
65
+ .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
66
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
67
+ .downcase
68
+ .to_sym
69
+ end
70
+
71
+ protected
72
+
73
+ # Validate password
74
+ # @raise [ArgumentError] If password is invalid
75
+ def validate_password
76
+ raise ArgumentError, "Password cannot be nil" if password.nil?
77
+ raise ArgumentError, "Password cannot be empty" if password.empty?
78
+ end
79
+
80
+ # Derive encryption key from password
81
+ # @param salt [String] Salt for key derivation
82
+ # @param iterations [Integer] Number of iterations
83
+ # @return [String] Derived key
84
+ def derive_key(salt, iterations = 1000)
85
+ require "openssl"
86
+ OpenSSL::PKCS5.pbkdf2_hmac(
87
+ password,
88
+ salt,
89
+ iterations,
90
+ 32, # 256 bits
91
+ OpenSSL::Digest.new("SHA256"),
92
+ )
93
+ end
94
+ end
95
+ end
96
+ end