Default to base 6 and release 0.2.0

This commit is contained in:
2026-09-16 09:33:26 -07:00
parent ea9e558bcc
commit 72a4aa8212
4 changed files with 31 additions and 9 deletions

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "zwus" name = "zwus"
version = "0.1.2" version = "0.2.0"
edition = "2021" edition = "2021"
rust-version = "1.70" rust-version = "1.70"
description = "Zero Width Unicode Steganography — hide text in invisible characters." description = "Zero Width Unicode Steganography — hide text in invisible characters."

View File

@@ -4,7 +4,7 @@ Zero Width Unicode Steganography — hide text inside invisible characters.
```toml ```toml
[dependencies] [dependencies]
zwus = "0.1" zwus = "0.2"
``` ```
## Usage ## Usage
@@ -28,14 +28,19 @@ assert_eq!(decoded, vec![72, 101, 108]);
Higher base = shorter output, but more likely visible in some renderers. Higher base = shorter output, but more likely visible in some renderers.
```rust ```rust
Zwus::encode_string_with_base("hi", 3); // default, safest use zwus::Zwus;
Zwus::encode_string_with_base("hi", 6); // compact
Zwus::encode_string_with_base("hi", 3); // safest
Zwus::encode_string_with_base("hi", 6); // default, compact
Zwus::encode_string_with_base("hi", 8); // most compact Zwus::encode_string_with_base("hi", 8); // most compact
``` ```
Decode must match the encode base: Decode must match the encode base:
```rust ```rust
use zwus::Zwus;
let encoded = Zwus::encode_string_with_base("hi", 6);
Zwus::decode_to_string_with_base(&encoded, 6); Zwus::decode_to_string_with_base(&encoded, 6);
``` ```
@@ -44,6 +49,8 @@ Zwus::decode_to_string_with_base(&encoded, 6);
Non-ZWUS characters are automatically ignored during decoding, so hidden payloads survive being mixed into normal text. Non-ZWUS characters are automatically ignored during decoding, so hidden payloads survive being mixed into normal text.
```rust ```rust
use zwus::Zwus;
let hidden = Zwus::encode_string("secret"); let hidden = Zwus::encode_string("secret");
let carrier = format!("nothing to see here{hidden}, move along"); let carrier = format!("nothing to see here{hidden}, move along");
let extracted = Zwus::decode_to_string(&carrier); let extracted = Zwus::decode_to_string(&carrier);
@@ -55,6 +62,8 @@ assert_eq!(extracted, "secret");
Handles emoji and all of Unicode — anything `char` can represent. Handles emoji and all of Unicode — anything `char` can represent.
```rust ```rust
use zwus::Zwus;
let encoded = Zwus::encode_string("hello 🦀🔥"); let encoded = Zwus::encode_string("hello 🦀🔥");
let decoded = Zwus::decode_to_string(&encoded); let decoded = Zwus::decode_to_string(&encoded);
assert_eq!(decoded, "hello 🦀🔥"); assert_eq!(decoded, "hello 🦀🔥");

View File

@@ -1,6 +1,6 @@
#![doc = include_str!("../README.md")] #![doc = include_str!("../README.md")]
pub const DEFAULT_BASE: u8 = 3; pub const DEFAULT_BASE: u8 = 6;
pub const SUPPORTED_BASES: [u8; 3] = [3, 6, 8]; pub const SUPPORTED_BASES: [u8; 3] = [3, 6, 8];
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
@@ -102,7 +102,7 @@ fn decode_numbers(text: &str, base: u8) -> Vec<u32> {
pub struct Zwus; pub struct Zwus;
impl Zwus { impl Zwus {
/// Encode a string using base 3 (default/safest). /// Encode a string using base 6 (default/compact).
pub fn encode_string(text: &str) -> String { pub fn encode_string(text: &str) -> String {
Self::encode_string_with_base(text, DEFAULT_BASE) Self::encode_string_with_base(text, DEFAULT_BASE)
} }
@@ -112,7 +112,7 @@ impl Zwus {
encode_numbers(text.chars().map(|c| c as u32), base) encode_numbers(text.chars().map(|c| c as u32), base)
} }
/// Encode numbers using base 3 (default/safest). /// Encode numbers using base 6 (default/compact).
pub fn encode_number_array(numbers: &[u32]) -> String { pub fn encode_number_array(numbers: &[u32]) -> String {
Self::encode_number_array_with_base(numbers, DEFAULT_BASE) Self::encode_number_array_with_base(numbers, DEFAULT_BASE)
} }
@@ -122,7 +122,7 @@ impl Zwus {
encode_numbers(numbers.iter().copied(), base) encode_numbers(numbers.iter().copied(), base)
} }
/// Decode to string using base 3 (default/safest). /// Decode to string using base 6 (default/compact).
/// Non-ZWUS chars are ignored automatically. /// Non-ZWUS chars are ignored automatically.
pub fn decode_to_string(text: &str) -> String { pub fn decode_to_string(text: &str) -> String {
Self::decode_to_string_with_base(text, DEFAULT_BASE) Self::decode_to_string_with_base(text, DEFAULT_BASE)
@@ -137,7 +137,7 @@ impl Zwus {
.collect() .collect()
} }
/// Decode to numbers using base 3 (default/safest). /// Decode to numbers using base 6 (default/compact).
/// Non-ZWUS chars are ignored automatically. /// Non-ZWUS chars are ignored automatically.
pub fn decode_to_number_array(text: &str) -> Vec<u32> { pub fn decode_to_number_array(text: &str) -> Vec<u32> {
Self::decode_to_number_array_with_base(text, DEFAULT_BASE) Self::decode_to_number_array_with_base(text, DEFAULT_BASE)

View File

@@ -1,5 +1,18 @@
use zwus::Zwus; use zwus::Zwus;
#[test]
fn default_base_is_6() {
let text = "secret 🦀";
let numbers = [0, 72, 101];
let encoded_text = Zwus::encode_string_with_base(text, 6);
let encoded_numbers = Zwus::encode_number_array_with_base(&numbers, 6);
assert_eq!(Zwus::encode_string(text), encoded_text);
assert_eq!(Zwus::decode_to_string(&encoded_text), text);
assert_eq!(Zwus::encode_number_array(&numbers), encoded_numbers);
assert_eq!(Zwus::decode_to_number_array(&encoded_numbers), numbers);
}
#[test] #[test]
fn roundtrip_string_base_3_6_8() { fn roundtrip_string_base_3_6_8() {
let text = "secret 🦀 unicode"; let text = "secret 🦀 unicode";