zeck 0.2.0 → 2.0.0

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.
package/README.md CHANGED
@@ -6,6 +6,8 @@ A Rust library for compressing and decompressing data using the Zeckendorf repre
6
6
 
7
7
  The Zeckendorf algorithm represents numbers as a sum of non-consecutive Fibonacci numbers. This library interprets input data as a big integer (either big-endian or little-endian), converts it to its Zeckendorf representation, and sometimes achieves compression. However, compression is not guaranteed; the algorithm may result in a larger representation depending on the input data. The library can automatically try both endian interpretations and select the one that produces the best compression.
8
8
 
9
+ **⚠️ Warning:** Compressing or decompressing files larger than 10KB (10,000 bytes) is unstable due to time and memory pressure. The library may experience performance issues, excessive memory usage, or failures when processing files exceeding this size.
10
+
9
11
  **Command-line tools** (`zeck-compress` and `zeck-decompress`) are available and can be installed via `cargo install zeck`. See the [Binaries](#binaries) section for usage details.
10
12
 
11
13
  ## Features
@@ -192,6 +194,8 @@ After installation, you can use `zeck-compress` and `zeck-decompress` directly f
192
194
 
193
195
  ### Compression/Decompression Tools
194
196
 
197
+ **⚠️ Warning:** Compressing or decompressing files larger than 10KB (10,000 bytes) is unstable due to time and memory pressure. The library may experience performance issues, excessive memory usage, or failures when processing files exceeding this size.
198
+
195
199
  #### zeck-compress
196
200
 
197
201
  Compresses data using the Zeckendorf representation algorithm. Automatically adds `.zbe` extension for big-endian compression and `.zle` extension for little-endian compression.
@@ -301,20 +305,20 @@ A playground/scratchpad for testing library functions.
301
305
  ### Generate Test Data
302
306
 
303
307
  ```bash
304
- cargo run --release --bin generate_data <size_in_bytes> [filename]
308
+ cargo run --release --bin zeck-generate-data --features development_tools -- <size_in_bytes> [filename]
305
309
  ```
306
310
 
307
311
  Generates random test data files in the `generated_data/` directory.
308
312
 
309
313
  Example:
310
314
  ```bash
311
- cargo run --release --bin generate_data 1024 my_file.bin
315
+ cargo run --release --bin zeck-generate-data --features development_tools -- 1024 my_file.bin
312
316
  ```
313
317
 
314
318
  ### Generate Statistics
315
319
 
316
320
  ```bash
317
- cargo run --release --bin generate_statistics --features plotting
321
+ cargo run --release --bin zeck-generate-statistics --features plotting,development_tools
318
322
  ```
319
323
 
320
324
  Generates comprehensive compression statistics and plots:
@@ -327,7 +331,7 @@ Generates comprehensive compression statistics and plots:
327
331
  ### Plot Compression Ratios
328
332
 
329
333
  ```bash
330
- cargo run --release --bin plot --features plotting
334
+ cargo run --release --bin zeck-plot --features plotting,development_tools
331
335
  ```
332
336
 
333
337
  Generates visualization plots of:
@@ -402,7 +406,29 @@ This avoids redundant Fibonacci numbers (F(0)=0 and F(1)=F(2)=1).
402
406
  - Compression is not guaranteed—some inputs may result in larger output
403
407
  - Compression effectiveness decreases as input size increases
404
408
  - The library supports both big-endian and little-endian interpretations, but other byte orderings or word boundaries are not currently explored
405
- - Compression of large amounts of data causes memory issues. It is currently not recommended to compress files larger than 100,000 bytes.
409
+ - **⚠️ Warning:** Compressing or decompressing files larger than 10KB (10,000 bytes) is unstable due to time and memory pressure. The library may experience performance issues, excessive memory usage, or failures when processing files exceeding this size.
410
+
411
+ ## NPM Versioning Quirk
412
+
413
+ For some reason, NPM was showing there were versions of zeck published between `1.0.0` and `1.0.6` from 2024, even though I never published them to npm. I don't know how this happened. So I bumped the version to `1.0.7` and was able to successfully publish it to npm. Maybe there was an old package with the same name that was deleted, and NPM is still showing the old versions.
414
+
415
+ Here is a snippet of the `time` object from the npm registry JSON (https://registry.npmjs.org/zeck):
416
+
417
+ ```json
418
+ "time": {
419
+ "created": "2026-01-02T20:19:14.018Z",
420
+ "modified": "2026-01-03T17:25:15.940Z",
421
+ "1.0.0": "2024-02-21T14:36:36.292Z",
422
+ "1.0.1": "2024-02-21T15:26:38.621Z",
423
+ "1.0.2": "2024-02-21T15:36:30.258Z",
424
+ "1.0.3": "2024-02-21T15:48:07.853Z",
425
+ "1.0.4": "2024-02-21T15:48:38.804Z",
426
+ "1.0.5": "2024-02-21T16:02:36.339Z",
427
+ "1.0.6": "2024-02-21T16:36:36.643Z",
428
+ "0.1.0": "2026-01-02T20:19:14.175Z",
429
+ "0.2.0": "2026-01-03T17:25:15.702Z"
430
+ },
431
+ ```
406
432
 
407
433
  ## License
408
434
 
package/package.json CHANGED
@@ -5,18 +5,17 @@
5
5
  "Peter Ryszkiewicz"
6
6
  ],
7
7
  "description": "A Rust library for compressing and decompressing data using the Zeckendorf representation algorithm",
8
- "version": "0.2.0",
8
+ "version": "2.0.0",
9
9
  "license": "MIT",
10
10
  "repository": {
11
11
  "type": "git",
12
- "url": "https://github.com/pRizz/zeckendorf"
12
+ "url": "https://github.com/pRizz/zeckendorf.git"
13
13
  },
14
14
  "files": [
15
15
  "zeck_bg.wasm",
16
16
  "zeck.js",
17
17
  "zeck_bg.js",
18
- "zeck.d.ts",
19
- "LICENSE.txt"
18
+ "zeck.d.ts"
20
19
  ],
21
20
  "main": "zeck.js",
22
21
  "types": "zeck.d.ts",
package/zeck.d.ts CHANGED
@@ -236,95 +236,153 @@ export function memoized_zeckendorf_list_descending_for_integer(n: bigint): BigU
236
236
  export function pack_ezba_bits_to_bytes(ezba: Uint8Array): Uint8Array;
237
237
 
238
238
  /**
239
- * Unpacks a vector of bytes into a vector of bits (0s and 1s) from an ezba (Effective Zeckendorf Bits Ascending).
239
+ * Compresses a slice of bytes using the Padless Zeckendorf Compression algorithm.
240
+ *
241
+ * Assumes the input data is interpreted as a big endian integer. The output data is in little endian order, so the first bit and byte is the least significant bit and byte and the last bit and byte is the most significant bit and byte.
242
+ *
243
+ * # ⚠️ Important: Original Size Preservation
244
+ *
245
+ * **This function strips leading zero bytes from the input data during compression.**
246
+ * It is the caller's responsibility to retain the original size information (e.g., `data.len()`)
247
+ * before calling this function. When decompressing, the original size must be used to pad the
248
+ * decompressed data with leading zeros to restore the exact original data. Without the original
249
+ * size, information will be lost during decompression.
250
+ *
251
+ * For a format that automatically handles size preservation, use [`crate::zeck_file_format::compress::compress_zeck_be`]
252
+ * instead, which includes a header with the original size information.
253
+ *
254
+ * # ⚠️ Warning
255
+ *
256
+ * **Compressing or decompressing data larger than 10KB (10,000 bytes) is unstable due to time and memory pressure.**
257
+ * The library may experience performance issues, excessive memory usage, or failures when processing data exceeding this size.
258
+ *
259
+ * TODO: Technically, the way the input data is interpreted is arbitrary; we could interpret it as little endian which could result in a more compact representation. We could go even further and interpret the data at different byte or word boundaries to see if it results in a more compact representation, and signify to the caller which interpretation was used. We probably need a better understanding of random distributions of data to determine what is the optimal interpretation. More investigation is needed here.
240
260
  *
241
261
  * # Examples
242
262
  *
243
263
  * ```
244
- * # use zeck::unpack_bytes_to_ezba_bits;
245
- * assert_eq!(unpack_bytes_to_ezba_bits(&[0]), vec![0, 0, 0, 0, 0, 0, 0, 0]);
246
- * assert_eq!(unpack_bytes_to_ezba_bits(&[1]), vec![1, 0, 0, 0, 0, 0, 0, 0]);
247
- * assert_eq!(unpack_bytes_to_ezba_bits(&[0b111]), vec![1, 1, 1, 0, 0, 0, 0, 0]);
248
- * assert_eq!(unpack_bytes_to_ezba_bits(&[1, 1]), vec![1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]);
264
+ * # use zeck::padless_zeckendorf_compress_be_dangerous;
265
+ * assert_eq!(padless_zeckendorf_compress_be_dangerous(&[0]), vec![0]);
266
+ * assert_eq!(padless_zeckendorf_compress_be_dangerous(&[1]), vec![1]);
267
+ * assert_eq!(padless_zeckendorf_compress_be_dangerous(&[12]), vec![0b111]);
268
+ * assert_eq!(padless_zeckendorf_compress_be_dangerous(&[54]), vec![30]);
269
+ * assert_eq!(padless_zeckendorf_compress_be_dangerous(&[55]), vec![0, 1]); // 55 is the 10 indexed Fibonacci number, which is the 8 indexed effective Fibonacci number, and therefore is the first number needing two bytes to contain these 8 bits, because there is 1 "use bit" and 7 "skip bits" in the effective zeckendorf bits ascending.
270
+ * assert_eq!(padless_zeckendorf_compress_be_dangerous(&[255]), vec![33, 2]);
271
+ * assert_eq!(padless_zeckendorf_compress_be_dangerous(&[1, 0]), vec![34, 2]);
249
272
  * ```
250
273
  */
251
- export function unpack_bytes_to_ezba_bits(bytes: Uint8Array): Uint8Array;
274
+ export function padless_zeckendorf_compress_be_dangerous(data: Uint8Array): Uint8Array;
252
275
 
253
276
  /**
254
- * Compresses a slice of bytes using the Zeckendorf algorithm.
277
+ * Compresses a slice of bytes using the Padless Zeckendorf Compression algorithm.
255
278
  *
256
- * Assumes the input data is interpreted as a big endian integer. The output data is in little endian order, so the first bit and byte is the least significant bit and byte and the last bit and byte is the most significant bit and byte.
279
+ * Assumes the input data is interpreted as a little endian integer. The output data is in little endian order, so the first bit and byte is the least significant bit and byte and the last bit and byte is the most significant bit and byte.
257
280
  *
258
- * TODO: Technically, the way the input data is interpreted is arbitrary; we could interpret it as little endian which could result in a more compact representation. We could go even further and interpret the data at different byte or word boundaries to see if it results in a more compact representation, and signify to the caller which interpretation was used. We probably need a better understanding of random distributions of data to determine what is the optimal interpretation. More investigation is needed here.
281
+ * # ⚠️ Important: Original Size Preservation
282
+ *
283
+ * **This function strips leading zero bytes from the input data during compression.**
284
+ * It is the caller's responsibility to retain the original size information (e.g., `data.len()`)
285
+ * before calling this function. When decompressing, the original size must be used to pad the
286
+ * decompressed data with leading zeros to restore the exact original data. Without the original
287
+ * size, information will be lost during decompression.
288
+ *
289
+ * For a format that automatically handles size preservation, use [`crate::zeck_file_format::compress::compress_zeck_le`]
290
+ * instead, which includes a header with the original size information.
291
+ *
292
+ * # ⚠️ Warning
293
+ *
294
+ * **Compressing or decompressing data larger than 10KB (10,000 bytes) is unstable due to time and memory pressure.**
295
+ * The library may experience performance issues, excessive memory usage, or failures when processing data exceeding this size.
259
296
  *
260
297
  * # Examples
261
298
  *
262
299
  * ```
263
- * # use zeck::zeckendorf_compress_be;
264
- * assert_eq!(zeckendorf_compress_be(&[0]), vec![0]);
265
- * assert_eq!(zeckendorf_compress_be(&[1]), vec![1]);
266
- * assert_eq!(zeckendorf_compress_be(&[12]), vec![0b111]);
267
- * assert_eq!(zeckendorf_compress_be(&[54]), vec![30]);
268
- * assert_eq!(zeckendorf_compress_be(&[55]), vec![0, 1]); // 55 is the 10 indexed Fibonacci number, which is the 8 indexed effective Fibonacci number, and therefore is the first number needing two bytes to contain these 8 bits, because there is 1 "use bit" and 7 "skip bits" in the effective zeckendorf bits ascending.
269
- * assert_eq!(zeckendorf_compress_be(&[255]), vec![33, 2]);
270
- * assert_eq!(zeckendorf_compress_be(&[1, 0]), vec![34, 2]);
300
+ * # use zeck::padless_zeckendorf_compress_le_dangerous;
301
+ * assert_eq!(padless_zeckendorf_compress_le_dangerous(&[0]), vec![0]);
302
+ * assert_eq!(padless_zeckendorf_compress_le_dangerous(&[1]), vec![1]);
303
+ * assert_eq!(padless_zeckendorf_compress_le_dangerous(&[12]), vec![0b111]);
304
+ * assert_eq!(padless_zeckendorf_compress_le_dangerous(&[54]), vec![30]);
305
+ * assert_eq!(padless_zeckendorf_compress_le_dangerous(&[55]), vec![0, 1]); // 55 is the 10 indexed Fibonacci number, which is the 8 indexed effective Fibonacci number, and therefore is the first number needing two bytes to contain these 8 bits, because there is 1 "use bit" and 7 "skip bits" in the effective zeckendorf bits ascending.
306
+ * assert_eq!(padless_zeckendorf_compress_le_dangerous(&[255]), vec![33, 2]);
307
+ * assert_eq!(padless_zeckendorf_compress_le_dangerous(&[0, 1]), vec![34, 2]);
271
308
  * ```
272
309
  */
273
- export function zeckendorf_compress_be(data: Uint8Array): Uint8Array;
310
+ export function padless_zeckendorf_compress_le_dangerous(data: Uint8Array): Uint8Array;
274
311
 
275
312
  /**
276
- * Compresses a slice of bytes using the Zeckendorf algorithm.
313
+ * Decompresses a slice of bytes compressed using the Zeckendorf algorithm, assuming the original data was compressed using the big endian bytes interpretation.
277
314
  *
278
- * Assumes the input data is interpreted as a little endian integer. The output data is in little endian order, so the first bit and byte is the least significant bit and byte and the last bit and byte is the most significant bit and byte.
315
+ * Assume the original input data was interpreted as a big endian integer, for now. See the TODO in the [`padless_zeckendorf_compress_be_dangerous`] function for more information.
316
+ *
317
+ * # ⚠️ Important: Leading Zero Padding
318
+ *
319
+ * **This function does not pad leading zero bytes.** If the original data had leading zeros, they will not be restored.
320
+ * The decompressed output will be the minimal representation of the number (without leading zeros).
321
+ *
322
+ * For a format that automatically handles size preservation and padding, use [`crate::zeck_file_format::file::deserialize_zeck_file`]
323
+ * and [`crate::zeck_file_format::decompress::decompress_zeck_file`] instead, which includes a header with the original size information and restores leading zeros.
324
+ *
325
+ * # ⚠️ Warning
326
+ *
327
+ * **Compressing or decompressing data larger than 10KB (10,000 bytes) is unstable due to time and memory pressure.**
328
+ * The library may experience performance issues, excessive memory usage, or failures when processing data exceeding this size.
279
329
  *
280
330
  * # Examples
281
331
  *
282
332
  * ```
283
- * # use zeck::zeckendorf_compress_le;
284
- * assert_eq!(zeckendorf_compress_le(&[0]), vec![0]);
285
- * assert_eq!(zeckendorf_compress_le(&[1]), vec![1]);
286
- * assert_eq!(zeckendorf_compress_le(&[12]), vec![0b111]);
287
- * assert_eq!(zeckendorf_compress_le(&[54]), vec![30]);
288
- * assert_eq!(zeckendorf_compress_le(&[55]), vec![0, 1]); // 55 is the 10 indexed Fibonacci number, which is the 8 indexed effective Fibonacci number, and therefore is the first number needing two bytes to contain these 8 bits, because there is 1 "use bit" and 7 "skip bits" in the effective zeckendorf bits ascending.
289
- * assert_eq!(zeckendorf_compress_le(&[255]), vec![33, 2]);
290
- * assert_eq!(zeckendorf_compress_le(&[0, 1]), vec![34, 2]);
333
+ * # use zeck::padless_zeckendorf_decompress_be_dangerous;
334
+ * assert_eq!(padless_zeckendorf_decompress_be_dangerous(&[0]), vec![0]);
335
+ * assert_eq!(padless_zeckendorf_decompress_be_dangerous(&[1]), vec![1]);
336
+ * assert_eq!(padless_zeckendorf_decompress_be_dangerous(&[0b111]), vec![12]);
337
+ * assert_eq!(padless_zeckendorf_decompress_be_dangerous(&[33, 2]), vec![255]);
338
+ * assert_eq!(padless_zeckendorf_decompress_be_dangerous(&[34, 2]), vec![1, 0]);
291
339
  * ```
292
340
  */
293
- export function zeckendorf_compress_le(data: Uint8Array): Uint8Array;
341
+ export function padless_zeckendorf_decompress_be_dangerous(compressed_data: Uint8Array): Uint8Array;
294
342
 
295
343
  /**
296
- * Decompresses a slice of bytes compressed using the Zeckendorf algorithm, assuming the original data was compressed using the big endian bytes interpretation.
344
+ * Decompresses a slice of bytes compressed using the Zeckendorf algorithm, assuming the original data was compressed using the little endian bytes interpretation.
345
+ *
346
+ * # ⚠️ Important: Leading Zero Padding
297
347
  *
298
- * Assume the original input data was interpreted as a big endian integer, for now. See the TODO in the [`zeckendorf_compress_be`] function for more information.
348
+ * **This function does not pad leading zero bytes.** If the original data had leading zeros, they will not be restored.
349
+ * The decompressed output will be the minimal representation of the number (without leading zeros).
350
+ *
351
+ * For a format that automatically handles size preservation and padding, use [`crate::zeck_file_format::file::deserialize_zeck_file`]
352
+ * and [`crate::zeck_file_format::decompress::decompress_zeck_file`] instead, which includes a header with the original size information and restores leading zeros.
353
+ *
354
+ * # ⚠️ Warning
355
+ *
356
+ * **Compressing or decompressing data larger than 10KB (10,000 bytes) is unstable due to time and memory pressure.**
357
+ * The library may experience performance issues, excessive memory usage, or failures when processing data exceeding this size.
299
358
  *
300
359
  * # Examples
301
360
  *
302
361
  * ```
303
- * # use zeck::zeckendorf_decompress_be;
304
- * assert_eq!(zeckendorf_decompress_be(&[0]), vec![0]);
305
- * assert_eq!(zeckendorf_decompress_be(&[1]), vec![1]);
306
- * assert_eq!(zeckendorf_decompress_be(&[0b111]), vec![12]);
307
- * assert_eq!(zeckendorf_decompress_be(&[33, 2]), vec![255]);
308
- * assert_eq!(zeckendorf_decompress_be(&[34, 2]), vec![1, 0]);
362
+ * # use zeck::padless_zeckendorf_decompress_le_dangerous;
363
+ * assert_eq!(padless_zeckendorf_decompress_le_dangerous(&[0]), vec![0]);
364
+ * assert_eq!(padless_zeckendorf_decompress_le_dangerous(&[1]), vec![1]);
365
+ * assert_eq!(padless_zeckendorf_decompress_le_dangerous(&[0b111]), vec![12]);
366
+ * assert_eq!(padless_zeckendorf_decompress_le_dangerous(&[33, 2]), vec![255]);
367
+ * assert_eq!(padless_zeckendorf_decompress_le_dangerous(&[34, 2]), vec![0, 1]);
309
368
  * ```
310
369
  */
311
- export function zeckendorf_decompress_be(compressed_data: Uint8Array): Uint8Array;
370
+ export function padless_zeckendorf_decompress_le_dangerous(compressed_data: Uint8Array): Uint8Array;
312
371
 
313
372
  /**
314
- * Decompresses a slice of bytes compressed using the Zeckendorf algorithm, assuming the original data was compressed using the little endian bytes interpretation.
373
+ * Unpacks a vector of bytes into a vector of bits (0s and 1s) from an ezba (Effective Zeckendorf Bits Ascending).
315
374
  *
316
375
  * # Examples
317
376
  *
318
377
  * ```
319
- * # use zeck::zeckendorf_decompress_le;
320
- * assert_eq!(zeckendorf_decompress_le(&[0]), vec![0]);
321
- * assert_eq!(zeckendorf_decompress_le(&[1]), vec![1]);
322
- * assert_eq!(zeckendorf_decompress_le(&[0b111]), vec![12]);
323
- * assert_eq!(zeckendorf_decompress_le(&[33, 2]), vec![255]);
324
- * assert_eq!(zeckendorf_decompress_le(&[34, 2]), vec![0, 1]);
378
+ * # use zeck::unpack_bytes_to_ezba_bits;
379
+ * assert_eq!(unpack_bytes_to_ezba_bits(&[0]), vec![0, 0, 0, 0, 0, 0, 0, 0]);
380
+ * assert_eq!(unpack_bytes_to_ezba_bits(&[1]), vec![1, 0, 0, 0, 0, 0, 0, 0]);
381
+ * assert_eq!(unpack_bytes_to_ezba_bits(&[0b111]), vec![1, 1, 1, 0, 0, 0, 0, 0]);
382
+ * assert_eq!(unpack_bytes_to_ezba_bits(&[1, 1]), vec![1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]);
325
383
  * ```
326
384
  */
327
- export function zeckendorf_decompress_le(compressed_data: Uint8Array): Uint8Array;
385
+ export function unpack_bytes_to_ezba_bits(bytes: Uint8Array): Uint8Array;
328
386
 
329
387
  /**
330
388
  * An Effective Zeckendorf List (EZL) has a lowest EFI of 0, which is an FI of 2.
package/zeck_bg.js CHANGED
@@ -353,136 +353,194 @@ export function pack_ezba_bits_to_bytes(ezba) {
353
353
  }
354
354
 
355
355
  /**
356
- * Unpacks a vector of bytes into a vector of bits (0s and 1s) from an ezba (Effective Zeckendorf Bits Ascending).
356
+ * Compresses a slice of bytes using the Padless Zeckendorf Compression algorithm.
357
+ *
358
+ * Assumes the input data is interpreted as a big endian integer. The output data is in little endian order, so the first bit and byte is the least significant bit and byte and the last bit and byte is the most significant bit and byte.
359
+ *
360
+ * # ⚠️ Important: Original Size Preservation
361
+ *
362
+ * **This function strips leading zero bytes from the input data during compression.**
363
+ * It is the caller's responsibility to retain the original size information (e.g., `data.len()`)
364
+ * before calling this function. When decompressing, the original size must be used to pad the
365
+ * decompressed data with leading zeros to restore the exact original data. Without the original
366
+ * size, information will be lost during decompression.
367
+ *
368
+ * For a format that automatically handles size preservation, use [`crate::zeck_file_format::compress::compress_zeck_be`]
369
+ * instead, which includes a header with the original size information.
370
+ *
371
+ * # ⚠️ Warning
372
+ *
373
+ * **Compressing or decompressing data larger than 10KB (10,000 bytes) is unstable due to time and memory pressure.**
374
+ * The library may experience performance issues, excessive memory usage, or failures when processing data exceeding this size.
375
+ *
376
+ * TODO: Technically, the way the input data is interpreted is arbitrary; we could interpret it as little endian which could result in a more compact representation. We could go even further and interpret the data at different byte or word boundaries to see if it results in a more compact representation, and signify to the caller which interpretation was used. We probably need a better understanding of random distributions of data to determine what is the optimal interpretation. More investigation is needed here.
357
377
  *
358
378
  * # Examples
359
379
  *
360
380
  * ```
361
- * # use zeck::unpack_bytes_to_ezba_bits;
362
- * assert_eq!(unpack_bytes_to_ezba_bits(&[0]), vec![0, 0, 0, 0, 0, 0, 0, 0]);
363
- * assert_eq!(unpack_bytes_to_ezba_bits(&[1]), vec![1, 0, 0, 0, 0, 0, 0, 0]);
364
- * assert_eq!(unpack_bytes_to_ezba_bits(&[0b111]), vec![1, 1, 1, 0, 0, 0, 0, 0]);
365
- * assert_eq!(unpack_bytes_to_ezba_bits(&[1, 1]), vec![1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]);
381
+ * # use zeck::padless_zeckendorf_compress_be_dangerous;
382
+ * assert_eq!(padless_zeckendorf_compress_be_dangerous(&[0]), vec![0]);
383
+ * assert_eq!(padless_zeckendorf_compress_be_dangerous(&[1]), vec![1]);
384
+ * assert_eq!(padless_zeckendorf_compress_be_dangerous(&[12]), vec![0b111]);
385
+ * assert_eq!(padless_zeckendorf_compress_be_dangerous(&[54]), vec![30]);
386
+ * assert_eq!(padless_zeckendorf_compress_be_dangerous(&[55]), vec![0, 1]); // 55 is the 10 indexed Fibonacci number, which is the 8 indexed effective Fibonacci number, and therefore is the first number needing two bytes to contain these 8 bits, because there is 1 "use bit" and 7 "skip bits" in the effective zeckendorf bits ascending.
387
+ * assert_eq!(padless_zeckendorf_compress_be_dangerous(&[255]), vec![33, 2]);
388
+ * assert_eq!(padless_zeckendorf_compress_be_dangerous(&[1, 0]), vec![34, 2]);
366
389
  * ```
367
- * @param {Uint8Array} bytes
390
+ * @param {Uint8Array} data
368
391
  * @returns {Uint8Array}
369
392
  */
370
- export function unpack_bytes_to_ezba_bits(bytes) {
371
- const ptr0 = passArray8ToWasm0(bytes, wasm.__wbindgen_malloc);
393
+ export function padless_zeckendorf_compress_be_dangerous(data) {
394
+ const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
372
395
  const len0 = WASM_VECTOR_LEN;
373
- const ret = wasm.unpack_bytes_to_ezba_bits(ptr0, len0);
396
+ const ret = wasm.padless_zeckendorf_compress_be_dangerous(ptr0, len0);
374
397
  var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
375
398
  wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
376
399
  return v2;
377
400
  }
378
401
 
379
402
  /**
380
- * Compresses a slice of bytes using the Zeckendorf algorithm.
403
+ * Compresses a slice of bytes using the Padless Zeckendorf Compression algorithm.
381
404
  *
382
- * Assumes the input data is interpreted as a big endian integer. The output data is in little endian order, so the first bit and byte is the least significant bit and byte and the last bit and byte is the most significant bit and byte.
405
+ * Assumes the input data is interpreted as a little endian integer. The output data is in little endian order, so the first bit and byte is the least significant bit and byte and the last bit and byte is the most significant bit and byte.
383
406
  *
384
- * TODO: Technically, the way the input data is interpreted is arbitrary; we could interpret it as little endian which could result in a more compact representation. We could go even further and interpret the data at different byte or word boundaries to see if it results in a more compact representation, and signify to the caller which interpretation was used. We probably need a better understanding of random distributions of data to determine what is the optimal interpretation. More investigation is needed here.
407
+ * # ⚠️ Important: Original Size Preservation
408
+ *
409
+ * **This function strips leading zero bytes from the input data during compression.**
410
+ * It is the caller's responsibility to retain the original size information (e.g., `data.len()`)
411
+ * before calling this function. When decompressing, the original size must be used to pad the
412
+ * decompressed data with leading zeros to restore the exact original data. Without the original
413
+ * size, information will be lost during decompression.
414
+ *
415
+ * For a format that automatically handles size preservation, use [`crate::zeck_file_format::compress::compress_zeck_le`]
416
+ * instead, which includes a header with the original size information.
417
+ *
418
+ * # ⚠️ Warning
419
+ *
420
+ * **Compressing or decompressing data larger than 10KB (10,000 bytes) is unstable due to time and memory pressure.**
421
+ * The library may experience performance issues, excessive memory usage, or failures when processing data exceeding this size.
385
422
  *
386
423
  * # Examples
387
424
  *
388
425
  * ```
389
- * # use zeck::zeckendorf_compress_be;
390
- * assert_eq!(zeckendorf_compress_be(&[0]), vec![0]);
391
- * assert_eq!(zeckendorf_compress_be(&[1]), vec![1]);
392
- * assert_eq!(zeckendorf_compress_be(&[12]), vec![0b111]);
393
- * assert_eq!(zeckendorf_compress_be(&[54]), vec![30]);
394
- * assert_eq!(zeckendorf_compress_be(&[55]), vec![0, 1]); // 55 is the 10 indexed Fibonacci number, which is the 8 indexed effective Fibonacci number, and therefore is the first number needing two bytes to contain these 8 bits, because there is 1 "use bit" and 7 "skip bits" in the effective zeckendorf bits ascending.
395
- * assert_eq!(zeckendorf_compress_be(&[255]), vec![33, 2]);
396
- * assert_eq!(zeckendorf_compress_be(&[1, 0]), vec![34, 2]);
426
+ * # use zeck::padless_zeckendorf_compress_le_dangerous;
427
+ * assert_eq!(padless_zeckendorf_compress_le_dangerous(&[0]), vec![0]);
428
+ * assert_eq!(padless_zeckendorf_compress_le_dangerous(&[1]), vec![1]);
429
+ * assert_eq!(padless_zeckendorf_compress_le_dangerous(&[12]), vec![0b111]);
430
+ * assert_eq!(padless_zeckendorf_compress_le_dangerous(&[54]), vec![30]);
431
+ * assert_eq!(padless_zeckendorf_compress_le_dangerous(&[55]), vec![0, 1]); // 55 is the 10 indexed Fibonacci number, which is the 8 indexed effective Fibonacci number, and therefore is the first number needing two bytes to contain these 8 bits, because there is 1 "use bit" and 7 "skip bits" in the effective zeckendorf bits ascending.
432
+ * assert_eq!(padless_zeckendorf_compress_le_dangerous(&[255]), vec![33, 2]);
433
+ * assert_eq!(padless_zeckendorf_compress_le_dangerous(&[0, 1]), vec![34, 2]);
397
434
  * ```
398
435
  * @param {Uint8Array} data
399
436
  * @returns {Uint8Array}
400
437
  */
401
- export function zeckendorf_compress_be(data) {
438
+ export function padless_zeckendorf_compress_le_dangerous(data) {
402
439
  const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
403
440
  const len0 = WASM_VECTOR_LEN;
404
- const ret = wasm.zeckendorf_compress_be(ptr0, len0);
441
+ const ret = wasm.padless_zeckendorf_compress_le_dangerous(ptr0, len0);
405
442
  var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
406
443
  wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
407
444
  return v2;
408
445
  }
409
446
 
410
447
  /**
411
- * Compresses a slice of bytes using the Zeckendorf algorithm.
448
+ * Decompresses a slice of bytes compressed using the Zeckendorf algorithm, assuming the original data was compressed using the big endian bytes interpretation.
412
449
  *
413
- * Assumes the input data is interpreted as a little endian integer. The output data is in little endian order, so the first bit and byte is the least significant bit and byte and the last bit and byte is the most significant bit and byte.
450
+ * Assume the original input data was interpreted as a big endian integer, for now. See the TODO in the [`padless_zeckendorf_compress_be_dangerous`] function for more information.
451
+ *
452
+ * # ⚠️ Important: Leading Zero Padding
453
+ *
454
+ * **This function does not pad leading zero bytes.** If the original data had leading zeros, they will not be restored.
455
+ * The decompressed output will be the minimal representation of the number (without leading zeros).
456
+ *
457
+ * For a format that automatically handles size preservation and padding, use [`crate::zeck_file_format::file::deserialize_zeck_file`]
458
+ * and [`crate::zeck_file_format::decompress::decompress_zeck_file`] instead, which includes a header with the original size information and restores leading zeros.
459
+ *
460
+ * # ⚠️ Warning
461
+ *
462
+ * **Compressing or decompressing data larger than 10KB (10,000 bytes) is unstable due to time and memory pressure.**
463
+ * The library may experience performance issues, excessive memory usage, or failures when processing data exceeding this size.
414
464
  *
415
465
  * # Examples
416
466
  *
417
467
  * ```
418
- * # use zeck::zeckendorf_compress_le;
419
- * assert_eq!(zeckendorf_compress_le(&[0]), vec![0]);
420
- * assert_eq!(zeckendorf_compress_le(&[1]), vec![1]);
421
- * assert_eq!(zeckendorf_compress_le(&[12]), vec![0b111]);
422
- * assert_eq!(zeckendorf_compress_le(&[54]), vec![30]);
423
- * assert_eq!(zeckendorf_compress_le(&[55]), vec![0, 1]); // 55 is the 10 indexed Fibonacci number, which is the 8 indexed effective Fibonacci number, and therefore is the first number needing two bytes to contain these 8 bits, because there is 1 "use bit" and 7 "skip bits" in the effective zeckendorf bits ascending.
424
- * assert_eq!(zeckendorf_compress_le(&[255]), vec![33, 2]);
425
- * assert_eq!(zeckendorf_compress_le(&[0, 1]), vec![34, 2]);
468
+ * # use zeck::padless_zeckendorf_decompress_be_dangerous;
469
+ * assert_eq!(padless_zeckendorf_decompress_be_dangerous(&[0]), vec![0]);
470
+ * assert_eq!(padless_zeckendorf_decompress_be_dangerous(&[1]), vec![1]);
471
+ * assert_eq!(padless_zeckendorf_decompress_be_dangerous(&[0b111]), vec![12]);
472
+ * assert_eq!(padless_zeckendorf_decompress_be_dangerous(&[33, 2]), vec![255]);
473
+ * assert_eq!(padless_zeckendorf_decompress_be_dangerous(&[34, 2]), vec![1, 0]);
426
474
  * ```
427
- * @param {Uint8Array} data
475
+ * @param {Uint8Array} compressed_data
428
476
  * @returns {Uint8Array}
429
477
  */
430
- export function zeckendorf_compress_le(data) {
431
- const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
478
+ export function padless_zeckendorf_decompress_be_dangerous(compressed_data) {
479
+ const ptr0 = passArray8ToWasm0(compressed_data, wasm.__wbindgen_malloc);
432
480
  const len0 = WASM_VECTOR_LEN;
433
- const ret = wasm.zeckendorf_compress_le(ptr0, len0);
481
+ const ret = wasm.padless_zeckendorf_decompress_be_dangerous(ptr0, len0);
434
482
  var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
435
483
  wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
436
484
  return v2;
437
485
  }
438
486
 
439
487
  /**
440
- * Decompresses a slice of bytes compressed using the Zeckendorf algorithm, assuming the original data was compressed using the big endian bytes interpretation.
488
+ * Decompresses a slice of bytes compressed using the Zeckendorf algorithm, assuming the original data was compressed using the little endian bytes interpretation.
489
+ *
490
+ * # ⚠️ Important: Leading Zero Padding
491
+ *
492
+ * **This function does not pad leading zero bytes.** If the original data had leading zeros, they will not be restored.
493
+ * The decompressed output will be the minimal representation of the number (without leading zeros).
494
+ *
495
+ * For a format that automatically handles size preservation and padding, use [`crate::zeck_file_format::file::deserialize_zeck_file`]
496
+ * and [`crate::zeck_file_format::decompress::decompress_zeck_file`] instead, which includes a header with the original size information and restores leading zeros.
441
497
  *
442
- * Assume the original input data was interpreted as a big endian integer, for now. See the TODO in the [`zeckendorf_compress_be`] function for more information.
498
+ * # ⚠️ Warning
499
+ *
500
+ * **Compressing or decompressing data larger than 10KB (10,000 bytes) is unstable due to time and memory pressure.**
501
+ * The library may experience performance issues, excessive memory usage, or failures when processing data exceeding this size.
443
502
  *
444
503
  * # Examples
445
504
  *
446
505
  * ```
447
- * # use zeck::zeckendorf_decompress_be;
448
- * assert_eq!(zeckendorf_decompress_be(&[0]), vec![0]);
449
- * assert_eq!(zeckendorf_decompress_be(&[1]), vec![1]);
450
- * assert_eq!(zeckendorf_decompress_be(&[0b111]), vec![12]);
451
- * assert_eq!(zeckendorf_decompress_be(&[33, 2]), vec![255]);
452
- * assert_eq!(zeckendorf_decompress_be(&[34, 2]), vec![1, 0]);
506
+ * # use zeck::padless_zeckendorf_decompress_le_dangerous;
507
+ * assert_eq!(padless_zeckendorf_decompress_le_dangerous(&[0]), vec![0]);
508
+ * assert_eq!(padless_zeckendorf_decompress_le_dangerous(&[1]), vec![1]);
509
+ * assert_eq!(padless_zeckendorf_decompress_le_dangerous(&[0b111]), vec![12]);
510
+ * assert_eq!(padless_zeckendorf_decompress_le_dangerous(&[33, 2]), vec![255]);
511
+ * assert_eq!(padless_zeckendorf_decompress_le_dangerous(&[34, 2]), vec![0, 1]);
453
512
  * ```
454
513
  * @param {Uint8Array} compressed_data
455
514
  * @returns {Uint8Array}
456
515
  */
457
- export function zeckendorf_decompress_be(compressed_data) {
516
+ export function padless_zeckendorf_decompress_le_dangerous(compressed_data) {
458
517
  const ptr0 = passArray8ToWasm0(compressed_data, wasm.__wbindgen_malloc);
459
518
  const len0 = WASM_VECTOR_LEN;
460
- const ret = wasm.zeckendorf_decompress_be(ptr0, len0);
519
+ const ret = wasm.padless_zeckendorf_decompress_le_dangerous(ptr0, len0);
461
520
  var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
462
521
  wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
463
522
  return v2;
464
523
  }
465
524
 
466
525
  /**
467
- * Decompresses a slice of bytes compressed using the Zeckendorf algorithm, assuming the original data was compressed using the little endian bytes interpretation.
526
+ * Unpacks a vector of bytes into a vector of bits (0s and 1s) from an ezba (Effective Zeckendorf Bits Ascending).
468
527
  *
469
528
  * # Examples
470
529
  *
471
530
  * ```
472
- * # use zeck::zeckendorf_decompress_le;
473
- * assert_eq!(zeckendorf_decompress_le(&[0]), vec![0]);
474
- * assert_eq!(zeckendorf_decompress_le(&[1]), vec![1]);
475
- * assert_eq!(zeckendorf_decompress_le(&[0b111]), vec![12]);
476
- * assert_eq!(zeckendorf_decompress_le(&[33, 2]), vec![255]);
477
- * assert_eq!(zeckendorf_decompress_le(&[34, 2]), vec![0, 1]);
531
+ * # use zeck::unpack_bytes_to_ezba_bits;
532
+ * assert_eq!(unpack_bytes_to_ezba_bits(&[0]), vec![0, 0, 0, 0, 0, 0, 0, 0]);
533
+ * assert_eq!(unpack_bytes_to_ezba_bits(&[1]), vec![1, 0, 0, 0, 0, 0, 0, 0]);
534
+ * assert_eq!(unpack_bytes_to_ezba_bits(&[0b111]), vec![1, 1, 1, 0, 0, 0, 0, 0]);
535
+ * assert_eq!(unpack_bytes_to_ezba_bits(&[1, 1]), vec![1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]);
478
536
  * ```
479
- * @param {Uint8Array} compressed_data
537
+ * @param {Uint8Array} bytes
480
538
  * @returns {Uint8Array}
481
539
  */
482
- export function zeckendorf_decompress_le(compressed_data) {
483
- const ptr0 = passArray8ToWasm0(compressed_data, wasm.__wbindgen_malloc);
540
+ export function unpack_bytes_to_ezba_bits(bytes) {
541
+ const ptr0 = passArray8ToWasm0(bytes, wasm.__wbindgen_malloc);
484
542
  const len0 = WASM_VECTOR_LEN;
485
- const ret = wasm.zeckendorf_decompress_le(ptr0, len0);
543
+ const ret = wasm.unpack_bytes_to_ezba_bits(ptr0, len0);
486
544
  var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
487
545
  wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
488
546
  return v2;
package/zeck_bg.wasm CHANGED
Binary file