Skip to content

Commit f035d95

Browse files
authored
feat: Base45 (#116)
Add support for Base54 encoding/decoding. Fixes #100.
1 parent eba2f98 commit f035d95

File tree

7 files changed

+37
-1
lines changed

7 files changed

+37
-1
lines changed

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,14 @@ keywords = ["ipld", "ipfs", "multihash", "cid", "no_std"]
1212

1313
[features]
1414
default = ["std"]
15-
std = ["data-encoding/std"]
15+
std = ["data-encoding/std", "base45/std"]
1616

1717
[dependencies]
1818
base-x = { version = "0.2.7", default-features = false }
1919
base256emoji = "1.0.2"
2020
data-encoding = { version = "2.3.1", default-features = false, features = ["alloc"] }
2121
data-encoding-macro = "0.1.9"
22+
base45 = { version = "3.2.0", default-features = false }
2223

2324
[dev-dependencies]
2425
criterion = "0.7"

cli/main.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ impl fmt::Display for StrBase {
8484
Base::Base32Z => "base32z",
8585
Base::Base36Lower => "base36lower",
8686
Base::Base36Upper => "base36upper",
87+
Base::Base45 => "base45",
8788
Base::Base58Flickr => "base58flickr",
8889
Base::Base58Btc => "base58btc",
8990
Base::Base64 => "base64",
@@ -118,6 +119,7 @@ impl FromStr for StrBase {
118119
"base32z" => Ok(Base::Base32Z),
119120
"base36lower" => Ok(Base::Base36Lower),
120121
"base36upper" => Ok(Base::Base36Upper),
122+
"base45" => Ok(Base::Base45),
121123
"base58flickr" => Ok(Base::Base58Flickr),
122124
"base58btc" => Ok(Base::Base58Btc),
123125
"base64" => Ok(Base::Base64),

src/base.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ build_base_enum! {
8282
'k' => Base36Lower,
8383
/// Base36, [0-9A-Z] no padding (alphabet: 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ).
8484
'K' => Base36Upper,
85+
/// Base45, rfc9285 (alphabet: 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:).
86+
'R' => Base45,
8587
/// Base58 flicker (alphabet: 123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ).
8688
'Z' => Base58Flickr,
8789
/// Base58 bitcoin (alphabet: 123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz).

src/error.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,9 @@ impl From<data_encoding::DecodeError> for Error {
4141
Self::InvalidBaseString
4242
}
4343
}
44+
45+
impl From<base45::DecodeError> for Error {
46+
fn from(_: base45::DecodeError) -> Self {
47+
Self::InvalidBaseString
48+
}
49+
}

src/impls.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,3 +158,17 @@ impl BaseCodec for Base36Upper {
158158
Ok(base_x::decode(encoding::BASE36_UPPER, &uppercased)?)
159159
}
160160
}
161+
162+
/// Base45, rfc9285 (alphabet: 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:).
163+
pub(crate) struct Base45;
164+
165+
impl BaseCodec for Base45 {
166+
fn encode<I: AsRef<[u8]>>(input: I) -> String {
167+
base45::encode(input.as_ref())
168+
}
169+
170+
fn decode<I: AsRef<str>>(input: I) -> Result<Vec<u8>> {
171+
let uppercased = input.as_ref().to_ascii_uppercase();
172+
Ok(base45::decode(&uppercased)?)
173+
}
174+
}

tests/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ fn test_basic() {
5858
(Base32Z, "hxf1zgedpcfzg1ebb"),
5959
(Base36Lower, "k2lcpzo5yikidynfl"),
6060
(Base36Upper, "K2LCPZO5YIKIDYNFL"),
61+
(Base45, "RRFF.OEB$D5/DZ24"),
6162
(Base58Flickr, "Z7Pznk19XTTzBtx"),
6263
(Base58Btc, "z7paNL19xttacUY"),
6364
(Base64, "meWVzIG1hbmkgIQ"),
@@ -90,6 +91,7 @@ fn preserves_leading_zero() {
9091
(Base32Z, "hybhskh3ypiosh4jyrr"),
9192
(Base36Lower, "k02lcpzo5yikidynfl"),
9293
(Base36Upper, "K02LCPZO5YIKIDYNFL"),
94+
(Base45, "RV206$CL44CEC2DDX0"),
9395
(Base58Flickr, "Z17Pznk19XTTzBtx"),
9496
(Base58Btc, "z17paNL19xttacUY"),
9597
(Base64, "mAHllcyBtYW5pICE"),
@@ -122,6 +124,7 @@ fn preserves_two_leading_zeroes() {
122124
(Base32Z, "hyyy813murbssn5ujryoo"),
123125
(Base36Lower, "k002lcpzo5yikidynfl"),
124126
(Base36Upper, "K002LCPZO5YIKIDYNFL"),
127+
(Base45, "R000RFF.OEB$D5/DZ24"),
125128
(Base58Flickr, "Z117Pznk19XTTzBtx"),
126129
(Base58Btc, "z117paNL19xttacUY"),
127130
(Base64, "mAAB5ZXMgbWFuaSAh"),
@@ -149,6 +152,7 @@ fn case_insensitivity() {
149152
(Base32HexPadUpper, "Td1imor3f41RMUSJCCG======"),
150153
(Base36Lower, "kfUvrsIvVnfRbjWaJo"),
151154
(Base36Upper, "KfUVrSIVVnFRbJWAJo"),
155+
(Base45, "R+8d vd82ek4f.kea2"),
152156
];
153157
for (base, output) in test_cases {
154158
assert_eq!(decode(output).unwrap(), (base, input.to_vec()));

0 commit comments

Comments
 (0)