Skip to content

Commit fe8908d

Browse files
committed
feat: add Base36 encoding
1 parent 3bd5157 commit fe8908d

File tree

5 files changed

+54
-8
lines changed

5 files changed

+54
-8
lines changed

cli/main.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ impl fmt::Display for StrBase {
6161
Base::Base32PadLower => "base32pad",
6262
Base::Base32PadUpper => "base32padupper",
6363
Base::Base32Z => "base32z",
64+
Base::Base36Lower => "base36lower",
65+
Base::Base36Upper => "base36upper",
6466
Base::Base58Flickr => "base58flickr",
6567
Base::Base58Btc => "base58btc",
6668
Base::Base64 => "base64",
@@ -92,6 +94,8 @@ impl FromStr for StrBase {
9294
"base32pad" => Ok(Base::Base32PadLower),
9395
"base32padupper" => Ok(Base::Base32PadUpper),
9496
"base32z" => Ok(Base::Base32Z),
97+
"base36lower" => Ok(Base::Base36Lower),
98+
"base36upper" => Ok(Base::Base36Upper),
9599
"base58flickr" => Ok(Base::Base58Flickr),
96100
"base58btc" => Ok(Base::Base58Btc),
97101
"base64" => Ok(Base::Base64),

src/base.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ build_base_enum! {
7575
'T' => Base32HexPadUpper,
7676
/// z-base-32 (used by Tahoe-LAFS) (alphabet: ybndrfg8ejkmcpqxot1uwisza345h769).
7777
'h' => Base32Z,
78+
/// Base36, [0-9a-z] no padding (alphabet: 0123456789abcdefghijklmnopqrstuvwxyz).
79+
'k' => Base36Lower,
80+
/// Base36, [0-9A-Z] no padding (alphabet: 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ).
81+
'K' => Base36Upper,
7882
/// Base58 flicker (alphabet: 123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ).
7983
'Z' => Base58Flickr,
8084
/// Base58 bitcoin (alphabet: 123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz).

src/encoding.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,12 @@ pub const BASE32Z: Encoding = new_encoding! {
8585
symbols: "ybndrfg8ejkmcpqxot1uwisza345h769",
8686
};
8787

88+
/// Base36, [0-9a-z] no padding (alphabet: 0123456789abcdefghijklmnopqrstuvwxyz).
89+
pub const BASE36_LOWER: &str = "0123456789abcdefghijklmnopqrstuvwxyz";
90+
91+
/// Base36, [0-9A-Z] no padding (alphabet: 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ).
92+
pub const BASE36_UPPER: &str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
93+
8894
// Base58 Flickr's alphabet for creating short urls from photo ids.
8995
pub const BASE58_FLICKR: &str = "123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ";
9096

src/impls.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,38 @@ impl BaseCodec for Base32Z {
219219
}
220220
}
221221

222+
/// Base36, [0-9a-z] no padding (alphabet: abcdefghijklmnopqrstuvwxyz0123456789).
223+
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
224+
pub(crate) struct Base36Lower;
225+
226+
impl BaseCodec for Base36Lower {
227+
fn encode<I: AsRef<[u8]>>(input: I) -> String {
228+
base_x::encode(encoding::BASE36_LOWER, input.as_ref())
229+
}
230+
231+
fn decode<I: AsRef<str>>(input: I) -> Result<Vec<u8>> {
232+
// The input is case insensitive, hence lowercase it
233+
let lowercased = input.as_ref().to_ascii_lowercase();
234+
Ok(base_x::decode(encoding::BASE36_LOWER, &lowercased)?)
235+
}
236+
}
237+
238+
/// Base36, [0-9A-Z] no padding (alphabet: ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789).
239+
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
240+
pub(crate) struct Base36Upper;
241+
242+
impl BaseCodec for Base36Upper {
243+
fn encode<I: AsRef<[u8]>>(input: I) -> String {
244+
base_x::encode(encoding::BASE36_UPPER, input.as_ref())
245+
}
246+
247+
fn decode<I: AsRef<str>>(input: I) -> Result<Vec<u8>> {
248+
// The input is case insensitive, hence uppercase it
249+
let uppercased = input.as_ref().to_ascii_uppercase();
250+
Ok(base_x::decode(encoding::BASE36_UPPER, &uppercased)?)
251+
}
252+
}
253+
222254
/// Base58 flicker (alphabet: 123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ).
223255
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
224256
pub(crate) struct Base58Flickr;

tests/lib.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ fn test_basic() {
5656
(Base32HexPadLower, "tf5in683dc5n6i811"),
5757
(Base32HexPadUpper, "TF5IN683DC5N6I811"),
5858
(Base32Z, "hxf1zgedpcfzg1ebb"),
59-
//(Base36Lower, "k2lcpzo5yikidynfl"),
60-
//(Base36Upper, "K2LCPZO5YIKIDYNFL"),
59+
(Base36Lower, "k2lcpzo5yikidynfl"),
60+
(Base36Upper, "K2LCPZO5YIKIDYNFL"),
6161
(Base58Flickr, "Z7Pznk19XTTzBtx"),
6262
(Base58Btc, "z7paNL19xttacUY"),
6363
(Base64, "meWVzIG1hbmkgIQ"),
@@ -87,8 +87,8 @@ fn preserves_leading_zero() {
8787
(Base32HexPadLower, "t01smasp0dlgmsq9044======"),
8888
(Base32HexPadUpper, "T01SMASP0DLGMSQ9044======"),
8989
(Base32Z, "hybhskh3ypiosh4jyrr"),
90-
//(Base36Lower, "k02lcpzo5yikidynfl"),
91-
//(Base36Upper, "K02LCPZO5YIKIDYNFL"),
90+
(Base36Lower, "k02lcpzo5yikidynfl"),
91+
(Base36Upper, "K02LCPZO5YIKIDYNFL"),
9292
(Base58Flickr, "Z17Pznk19XTTzBtx"),
9393
(Base58Btc, "z17paNL19xttacUY"),
9494
(Base64, "mAHllcyBtYW5pICE"),
@@ -118,8 +118,8 @@ fn preserves_two_leading_zeroes() {
118118
(Base32HexPadLower, "t0007ipbj41mm2rj940gg===="),
119119
(Base32HexPadUpper, "T0007IPBJ41MM2RJ940GG===="),
120120
(Base32Z, "hyyy813murbssn5ujryoo"),
121-
//(Base36Lower, "k002lcpzo5yikidynfl"),
122-
//(Base36Upper, "K002LCPZO5YIKIDYNFL"),
121+
(Base36Lower, "k002lcpzo5yikidynfl"),
122+
(Base36Upper, "K002LCPZO5YIKIDYNFL"),
123123
(Base58Flickr, "Z117Pznk19XTTzBtx"),
124124
(Base58Btc, "z117paNL19xttacUY"),
125125
(Base64, "mAAB5ZXMgbWFuaSAh"),
@@ -145,8 +145,8 @@ fn case_insensitivity() {
145145
(Base32PadUpper, "Cnbswy3dpeB3W64TMMQ======"),
146146
(Base32HexPadLower, "td1imor3f41RMUSJCCG======"),
147147
(Base32HexPadUpper, "Td1imor3f41RMUSJCCG======"),
148-
//(Base36Lower, "kfUvrsIvVnfRbjWaJo"),
149-
//(Base36Upper, "KfUVrSIVVnFRbJWAJo"),
148+
(Base36Lower, "kfUvrsIvVnfRbjWaJo"),
149+
(Base36Upper, "KfUVrSIVVnFRbJWAJo"),
150150
];
151151
for (base, output) in test_cases {
152152
assert_eq!(decode(output).unwrap(), (base, input.to_vec()));

0 commit comments

Comments
 (0)