Skip to content

Commit 35a261e

Browse files
author
Dave Grantham
committed
lazy decoding
Signed-off-by: Dave Grantham <dwg@linuxprogrammer.org>
1 parent 40cc58b commit 35a261e

File tree

7 files changed

+119
-61
lines changed

7 files changed

+119
-61
lines changed

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "multibase"
3-
version = "0.9.1"
4-
authors = ["Friedel Ziegelmayer <dignifiedquire@gmail.com>"]
3+
version = "1.0.0"
4+
authors = ["Friedel Ziegelmayer <dignifiedquire@gmail.com>", "Dave Grantham <dwg@linuxprogrammer.org>"]
55
edition = "2018"
66
license = "MIT"
77
readme = "README.md"

benches/multibase.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,17 +53,17 @@ fn bench_decode(c: &mut Criterion) {
5353
let mut group = c.benchmark_group("decode");
5454
group.bench_function("base32", |b| {
5555
b.iter(|| {
56-
let _ = black_box(decode(&base32_data).unwrap());
56+
let _ = black_box(decode(&base32_data, false).unwrap());
5757
})
5858
});
5959
group.bench_function("base58btc", |b| {
6060
b.iter(|| {
61-
let _ = black_box(decode(&base58_data).unwrap());
61+
let _ = black_box(decode(&base58_data, false).unwrap());
6262
})
6363
});
6464
group.bench_function("base64", |b| {
6565
b.iter(|| {
66-
let _ = black_box(decode(&base64_data).unwrap());
66+
let _ = black_box(decode(&base64_data, false).unwrap());
6767
})
6868
});
6969
group.finish();

src/base.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ macro_rules! build_base_enum {
3838
}
3939

4040
/// Decode the base string.
41-
pub fn decode<I: AsRef<str>>(&self, input: I) -> Result<Vec<u8>> {
41+
pub fn decode<I: AsRef<str>>(&self, input: I, strict: bool) -> Result<Vec<u8>> {
4242
match self {
43-
$( Self::$base => $base::decode(input), )*
43+
$( Self::$base => $base::decode(input, strict), )*
4444
}
4545
}
4646
}
@@ -94,6 +94,6 @@ build_base_enum! {
9494
'u' => Base64Url,
9595
/// Base64 url, rfc4648 with padding (alphabet: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_).
9696
'U' => Base64UrlPad,
97-
/// Base256Emoji (alphabet: 🚀🪐☄🛰🌌🌑🌒🌓🌔🌕🌖🌗🌘🌍🌏🌎🐉☀💻🖥💾💿😂❤😍🤣😊🙏💕😭😘👍😅👏😁🔥🥰💔💖💙😢🤔😆🙄💪😉☺👌🤗💜😔😎😇🌹🤦🎉💞✌✨🤷😱😌🌸🙌😋💗💚😏💛🙂💓🤩😄😀🖤😃💯🙈👇🎶😒🤭❣😜💋👀😪😑💥🙋😞😩😡🤪👊🥳😥🤤👉💃😳✋😚😝😴🌟😬🙃🍀🌷😻😓⭐✅🥺🌈😈🤘💦✔😣🏃💐☹🎊💘😠☝😕🌺🎂🌻😐🖕💝🙊😹🗣💫💀👑🎵🤞😛🔴😤🌼😫⚽🤙☕🏆🤫👈😮🙆🍻🍃🐶💁😲🌿🧡🎁⚡🌞🎈❌✊👋😰🤨😶🤝🚶💰🍓💢🤟🙁🚨💨🤬✈🎀🍺🤓😙💟🌱😖👶🥴▶➡❓💎💸⬇😨🌚🦋😷🕺⚠🙅😟😵👎🤲🤠🤧📌🔵💅🧐🐾🍒😗🤑🌊🤯🐷☎💧😯💆👆🎤🙇🍑❄🌴💣🐸💌📍🥀🤢👅💡💩👐📸👻🤐🤮🎼🥵🚩🍎🍊👼💍📣🥂)
97+
/// Base256Emoji (alphabet: 🚀🪐☄🛰🌌🌑🌒🌓🌔🌕🌖🌗🌘🌍🌏🌎🐉☀💻🖥💾💿😂❤😍🤣😊🙏💕😭😘👍😅👏😁🔥🥰💔💖💙😢🤔😆🙄💪😉☺👌🤗💜😔😎😇🌹🤦🎉💞✌✨🤷😱😌🌸🙌😋💗💚😏💛🙂💓🤩😄😀🖤😃💯🙈👇🎶😒🤭❣😜💋👀😪😑💥🙋😞😩😡🤪👊🥳😥🤤👉💃😳✋😚😝😴🌟😬🙃🍀🌷😻😓⭐✅🥺🌈😈🤘💦✔😣🏃💐☹🎊💘😠☝😕🌺🎂🌻😐🖕💝🙊😹🗣💫💀👑🎵🤞😛🔴😤🌼😫⚽🤙☕🏆🤫👈😮🙆🍻🍃🐶💁😲🌿🧡🎁⚡🌞🎈❌✊👋😰🤨😶🤝🚶💰🍓💢🤟🙁🚨💨🤬✈🎀🍺🤓😙💟🌱😖👶🥴▶➡❓💎💸⬇😨🌚🦋😷🕺⚠🙅😟😵👎🤲🤠🤧📌🔵💅🧐🐾🍒😗🤑🌊🤯🐷☎💧😯💆👆🎤🙇🍑❄🌴💣🐸💌📍🥀🤢👅💡💩👐📸👻🤐🤮🎼🥵🚩🍎🍊👼💍📣🥂)
9898
'🚀' => Base256Emoji,
9999
}

src/encoding.rs

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,109 +2,151 @@ use data_encoding::Encoding;
22
use data_encoding_macro::new_encoding;
33

44
// Base2 (alphabet: 01)
5+
pub const BASE2_PERMISSIVE: Encoding = BASE2;
56
pub const BASE2: Encoding = new_encoding! {
67
symbols: "01",
78
};
89

910
// Base8 (alphabet: 01234567)
11+
pub const BASE8_PERMISSIVE: Encoding = BASE8;
1012
pub const BASE8: Encoding = new_encoding! {
1113
symbols: "01234567",
1214
};
1315

1416
/// Base10 (alphabet: 0123456789)
17+
pub const BASE10_PERMISSIVE: &str = BASE10;
1518
pub const BASE10: &str = "0123456789";
1619

1720
// Base16 lower hexadecimal (alphabet: 0123456789abcdef)
18-
pub const BASE16_LOWER: Encoding = data_encoding::HEXLOWER_PERMISSIVE;
21+
pub const BASE16_LOWER_PERMISSIVE: Encoding = data_encoding::HEXLOWER_PERMISSIVE;
22+
pub const BASE16_LOWER: Encoding = data_encoding::HEXLOWER;
1923

2024
// Base16 upper hexadecimal (alphabet: 0123456789ABCDEF).
21-
pub const BASE16_UPPER: Encoding = data_encoding::HEXUPPER_PERMISSIVE;
25+
pub const BASE16_UPPER_PERMISSIVE: Encoding = data_encoding::HEXUPPER_PERMISSIVE;
26+
pub const BASE16_UPPER: Encoding = data_encoding::HEXUPPER;
2227

2328
// Base32, rfc4648 no padding (alphabet: abcdefghijklmnopqrstuvwxyz234567).
24-
pub const BASE32_NOPAD_LOWER: Encoding = new_encoding! {
29+
pub const BASE32_NOPAD_LOWER_PERMISSIVE: Encoding = new_encoding! {
2530
symbols: "abcdefghijklmnopqrstuvwxyz234567",
2631
translate_from: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
2732
translate_to: "abcdefghijklmnopqrstuvwxyz",
2833
};
34+
pub const BASE32_NOPAD_LOWER: Encoding = new_encoding! {
35+
symbols: "abcdefghijklmnopqrstuvwxyz234567",
36+
};
2937

3038
// Base32, rfc4648 no padding (alphabet: ABCDEFGHIJKLMNOPQRSTUVWXYZ234567).
31-
pub const BASE32_NOPAD_UPPER: Encoding = new_encoding! {
39+
pub const BASE32_NOPAD_UPPER_PERMISSIVE: Encoding = new_encoding! {
3240
symbols: "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567",
3341
translate_from: "abcdefghijklmnopqrstuvwxyz",
3442
translate_to: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
3543
};
44+
pub const BASE32_NOPAD_UPPER: Encoding = new_encoding! {
45+
symbols: "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567",
46+
};
3647

3748
// Base32, rfc4648 with padding (alphabet: abcdefghijklmnopqrstuvwxyz234567).
38-
pub const BASE32_PAD_LOWER: Encoding = new_encoding! {
49+
pub const BASE32_PAD_LOWER_PERMISSIVE: Encoding = new_encoding! {
3950
symbols: "abcdefghijklmnopqrstuvwxyz234567",
4051
translate_from: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
4152
translate_to: "abcdefghijklmnopqrstuvwxyz",
4253
padding: '=',
4354
};
55+
pub const BASE32_PAD_LOWER: Encoding = new_encoding! {
56+
symbols: "abcdefghijklmnopqrstuvwxyz234567",
57+
padding: '=',
58+
};
4459

4560
// Base32, rfc4648 with padding (alphabet: ABCDEFGHIJKLMNOPQRSTUVWXYZ234567).
46-
pub const BASE32_PAD_UPPER: Encoding = new_encoding! {
61+
pub const BASE32_PAD_UPPER_PERMISSIVE: Encoding = new_encoding! {
4762
symbols: "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567",
4863
translate_from: "abcdefghijklmnopqrstuvwxyz",
4964
translate_to: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
5065
padding: '=',
5166
};
67+
pub const BASE32_PAD_UPPER: Encoding = new_encoding! {
68+
symbols: "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567",
69+
padding: '=',
70+
};
5271

5372
// Base32hex, rfc4648 no padding (alphabet: 0123456789abcdefghijklmnopqrstuv).
54-
pub const BASE32HEX_NOPAD_LOWER: Encoding = new_encoding! {
73+
pub const BASE32HEX_NOPAD_LOWER_PERMISSIVE: Encoding = new_encoding! {
5574
symbols: "0123456789abcdefghijklmnopqrstuv",
5675
translate_from: "ABCDEFGHIJKLMNOPQRSTUV",
5776
translate_to: "abcdefghijklmnopqrstuv",
5877
};
78+
pub const BASE32HEX_NOPAD_LOWER: Encoding = new_encoding! {
79+
symbols: "0123456789abcdefghijklmnopqrstuv",
80+
};
5981

6082
// Base32hex, rfc4648 no padding (alphabet: 0123456789ABCDEFGHIJKLMNOPQRSTUV).
61-
pub const BASE32HEX_NOPAD_UPPER: Encoding = new_encoding! {
83+
pub const BASE32HEX_NOPAD_UPPER_PERMISSIVE: Encoding = new_encoding! {
6284
symbols: "0123456789ABCDEFGHIJKLMNOPQRSTUV",
6385
translate_from: "abcdefghijklmnopqrstuv",
6486
translate_to: "ABCDEFGHIJKLMNOPQRSTUV",
6587
};
88+
pub const BASE32HEX_NOPAD_UPPER: Encoding = new_encoding! {
89+
symbols: "0123456789ABCDEFGHIJKLMNOPQRSTUV",
90+
};
6691

6792
// Base32hex, rfc4648 with padding (alphabet: 0123456789abcdefghijklmnopqrstuv).
68-
pub const BASE32HEX_PAD_LOWER: Encoding = new_encoding! {
93+
pub const BASE32HEX_PAD_LOWER_PERMISSIVE: Encoding = new_encoding! {
6994
symbols: "0123456789abcdefghijklmnopqrstuv",
7095
translate_from: "ABCDEFGHIJKLMNOPQRSTUV",
7196
translate_to: "abcdefghijklmnopqrstuv",
7297
padding: '=',
7398
};
99+
pub const BASE32HEX_PAD_LOWER: Encoding = new_encoding! {
100+
symbols: "0123456789abcdefghijklmnopqrstuv",
101+
padding: '=',
102+
};
74103

75104
/// Base32hex, rfc4648 with padding (alphabet: 0123456789ABCDEFGHIJKLMNOPQRSTUV).
76-
pub const BASE32HEX_PAD_UPPER: Encoding = new_encoding! {
105+
pub const BASE32HEX_PAD_UPPER_PERMISSIVE: Encoding = new_encoding! {
77106
symbols: "0123456789ABCDEFGHIJKLMNOPQRSTUV",
78107
translate_from: "abcdefghijklmnopqrstuv",
79108
translate_to: "ABCDEFGHIJKLMNOPQRSTUV",
80109
padding: '=',
81110
};
111+
pub const BASE32HEX_PAD_UPPER: Encoding = new_encoding! {
112+
symbols: "0123456789ABCDEFGHIJKLMNOPQRSTUV",
113+
padding: '=',
114+
};
82115

83116
// z-base-32 (used by Tahoe-LAFS) (alphabet: ybndrfg8ejkmcpqxot1uwisza345h769).
117+
pub const BASE32Z_PERMISSIVE: Encoding = BASE32Z;
84118
pub const BASE32Z: Encoding = new_encoding! {
85119
symbols: "ybndrfg8ejkmcpqxot1uwisza345h769",
86120
};
87121

88122
/// Base36, [0-9a-z] no padding (alphabet: 0123456789abcdefghijklmnopqrstuvwxyz).
123+
pub const BASE36_LOWER_PERMISSIVE: &str = BASE36_LOWER;
89124
pub const BASE36_LOWER: &str = "0123456789abcdefghijklmnopqrstuvwxyz";
90125

91126
/// Base36, [0-9A-Z] no padding (alphabet: 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ).
127+
pub const BASE36_UPPER_PERMISSIVE: &str = BASE36_UPPER;
92128
pub const BASE36_UPPER: &str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
93129

94130
// Base58 Flickr's alphabet for creating short urls from photo ids.
131+
pub const BASE58_FLICKR_PERMISSIVE: &str = BASE58_FLICKR;
95132
pub const BASE58_FLICKR: &str = "123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ";
96133

97134
// Base58 Bitcoin's alphabet as defined in their Base58Check encoding.
135+
pub const BASE58_BITCOIN_PERMISSIVE: &str = BASE58_BITCOIN;
98136
pub const BASE58_BITCOIN: &str = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
99137

100138
// Base64, rfc4648 no padding (alphabet: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/).
139+
pub const BASE64_NOPAD_PERMISSIVE: Encoding = BASE64_NOPAD;
101140
pub const BASE64_NOPAD: Encoding = data_encoding::BASE64_NOPAD;
102141

103142
// Base64, rfc4648 with padding (alphabet: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/).
143+
pub const BASE64_PAD_PERMISSIVE: Encoding = BASE64_PAD;
104144
pub const BASE64_PAD: Encoding = data_encoding::BASE64;
105145

106146
// Base64 url, rfc4648 no padding (alphabet: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_).
147+
pub const BASE64URL_NOPAD_PERMISSIVE: Encoding = BASE64URL_NOPAD;
107148
pub const BASE64URL_NOPAD: Encoding = data_encoding::BASE64URL_NOPAD;
108149

109150
// Base64 url, rfc4648 with padding (alphabet: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_).
151+
pub const BASE64URL_PAD_PERMISSIVE: Encoding = BASE64URL_PAD;
110152
pub const BASE64URL_PAD: Encoding = data_encoding::BASE64URL;

src/impls.rs

Lines changed: 53 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use base256emoji::{Base, Emoji};
66
use alloc::{string::String, vec::Vec};
77

88
macro_rules! derive_base_encoding {
9-
( $(#[$doc:meta] $type:ident, $encoding:expr;)* ) => {
9+
( $(#[$doc:meta] $type:ident, $encoding:expr, $permissive:expr;)* ) => {
1010
$(
1111
#[$doc]
1212
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
@@ -17,16 +17,20 @@ macro_rules! derive_base_encoding {
1717
$encoding.encode(input.as_ref())
1818
}
1919

20-
fn decode<I: AsRef<str>>(input: I) -> Result<Vec<u8>> {
21-
Ok($encoding.decode(input.as_ref().as_bytes())?)
20+
fn decode<I: AsRef<str>>(input: I, strict: bool) -> Result<Vec<u8>> {
21+
if strict {
22+
Ok($encoding.decode(input.as_ref().as_bytes())?)
23+
} else {
24+
Ok($permissive.decode(input.as_ref().as_bytes())?)
25+
}
2226
}
2327
}
2428
)*
2529
};
2630
}
2731

2832
macro_rules! derive_base_x {
29-
( $(#[$doc:meta] $type:ident, $encoding:expr;)* ) => {
33+
( $(#[$doc:meta] $type:ident, $encoding:expr, $permissive:expr;)* ) => {
3034
$(
3135
#[$doc]
3236
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
@@ -37,8 +41,12 @@ macro_rules! derive_base_x {
3741
base_x::encode($encoding, input.as_ref())
3842
}
3943

40-
fn decode<I: AsRef<str>>(input: I) -> Result<Vec<u8>> {
41-
Ok(base_x::decode($encoding, input.as_ref())?)
44+
fn decode<I: AsRef<str>>(input: I, strict: bool) -> Result<Vec<u8>> {
45+
if strict {
46+
Ok(base_x::decode($encoding, input.as_ref())?)
47+
} else {
48+
Ok(base_x::decode($permissive, input.as_ref())?)
49+
}
4250
}
4351
}
4452
)*
@@ -50,7 +58,7 @@ pub(crate) trait BaseCodec {
5058
fn encode<I: AsRef<[u8]>>(input: I) -> String;
5159

5260
/// Decode with the given string.
53-
fn decode<I: AsRef<str>>(input: I) -> Result<Vec<u8>>;
61+
fn decode<I: AsRef<str>>(input: I, strict: bool) -> Result<Vec<u8>>;
5462
}
5563

5664
/// Identity, 8-bit binary (encoder and decoder keeps data unmodified).
@@ -62,7 +70,7 @@ impl BaseCodec for Identity {
6270
String::from_utf8(input.as_ref().to_vec()).expect("input must be valid UTF-8 bytes")
6371
}
6472

65-
fn decode<I: AsRef<str>>(input: I) -> Result<Vec<u8>> {
73+
fn decode<I: AsRef<str>>(input: I, _strict: bool) -> Result<Vec<u8>> {
6674
Ok(input.as_ref().as_bytes().to_vec())
6775
}
6876
}
@@ -76,55 +84,55 @@ impl BaseCodec for Base256Emoji {
7684
Emoji::encode(input.as_ref())
7785
}
7886

79-
fn decode<I: AsRef<str>>(input: I) -> Result<Vec<u8>> {
87+
fn decode<I: AsRef<str>>(input: I, _strict: bool) -> Result<Vec<u8>> {
8088
Emoji::decode(input.as_ref()).map_err(|e| e.into())
8189
}
8290
}
8391

8492
derive_base_encoding! {
8593
/// Base2 (alphabet: 01).
86-
Base2, encoding::BASE2;
94+
Base2, encoding::BASE2, encoding::BASE2_PERMISSIVE;
8795
/// Base8 (alphabet: 01234567).
88-
Base8, encoding::BASE8;
96+
Base8, encoding::BASE8, encoding::BASE8_PERMISSIVE;
8997
/// Base16 lower hexadecimal (alphabet: 0123456789abcdef).
90-
Base16Lower, encoding::BASE16_LOWER;
98+
Base16Lower, encoding::BASE16_LOWER, encoding::BASE16_LOWER_PERMISSIVE;
9199
/// Base16 upper hexadecimal (alphabet: 0123456789ABCDEF).
92-
Base16Upper, encoding::BASE16_UPPER;
100+
Base16Upper, encoding::BASE16_UPPER, encoding::BASE16_UPPER_PERMISSIVE;
93101
/// Base32, rfc4648 no padding (alphabet: abcdefghijklmnopqrstuvwxyz234567).
94-
Base32Lower, encoding::BASE32_NOPAD_LOWER;
102+
Base32Lower, encoding::BASE32_NOPAD_LOWER, encoding::BASE32_NOPAD_LOWER_PERMISSIVE;
95103
/// Base32, rfc4648 no padding (alphabet: ABCDEFGHIJKLMNOPQRSTUVWXYZ234567).
96-
Base32Upper, encoding::BASE32_NOPAD_UPPER;
104+
Base32Upper, encoding::BASE32_NOPAD_UPPER, encoding::BASE32_NOPAD_UPPER_PERMISSIVE;
97105
/// Base32, rfc4648 with padding (alphabet: abcdefghijklmnopqrstuvwxyz234567).
98-
Base32PadLower, encoding::BASE32_PAD_LOWER;
106+
Base32PadLower, encoding::BASE32_PAD_LOWER, encoding::BASE32_PAD_LOWER_PERMISSIVE;
99107
/// Base32, rfc4648 with padding (alphabet: ABCDEFGHIJKLMNOPQRSTUVWXYZ234567).
100-
Base32PadUpper, encoding::BASE32_PAD_UPPER;
108+
Base32PadUpper, encoding::BASE32_PAD_UPPER, encoding::BASE32_PAD_UPPER_PERMISSIVE;
101109
/// Base32hex, rfc4648 no padding (alphabet: 0123456789abcdefghijklmnopqrstuv).
102-
Base32HexLower, encoding::BASE32HEX_NOPAD_LOWER;
110+
Base32HexLower, encoding::BASE32HEX_NOPAD_LOWER, encoding::BASE32HEX_NOPAD_LOWER_PERMISSIVE;
103111
/// Base32hex, rfc4648 no padding (alphabet: 0123456789ABCDEFGHIJKLMNOPQRSTUV).
104-
Base32HexUpper, encoding::BASE32HEX_NOPAD_UPPER;
112+
Base32HexUpper, encoding::BASE32HEX_NOPAD_UPPER, encoding::BASE32HEX_NOPAD_UPPER_PERMISSIVE;
105113
/// Base32hex, rfc4648 with padding (alphabet: 0123456789abcdefghijklmnopqrstuv).
106-
Base32HexPadLower, encoding::BASE32HEX_PAD_LOWER;
114+
Base32HexPadLower, encoding::BASE32HEX_PAD_LOWER, encoding::BASE32HEX_PAD_LOWER_PERMISSIVE;
107115
/// Base32hex, rfc4648 with padding (alphabet: 0123456789ABCDEFGHIJKLMNOPQRSTUV).
108-
Base32HexPadUpper, encoding::BASE32HEX_PAD_UPPER;
116+
Base32HexPadUpper, encoding::BASE32HEX_PAD_UPPER, encoding::BASE32HEX_PAD_UPPER_PERMISSIVE;
109117
/// z-base-32 (used by Tahoe-LAFS) (alphabet: ybndrfg8ejkmcpqxot1uwisza345h769).
110-
Base32Z, encoding::BASE32Z;
118+
Base32Z, encoding::BASE32Z, encoding::BASE32Z_PERMISSIVE;
111119
/// Base64, rfc4648 no padding (alphabet: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/).
112-
Base64, encoding::BASE64_NOPAD;
120+
Base64, encoding::BASE64_NOPAD, encoding::BASE64_NOPAD_PERMISSIVE;
113121
/// Base64, rfc4648 with padding (alphabet: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/).
114-
Base64Pad, encoding::BASE64_PAD;
122+
Base64Pad, encoding::BASE64_PAD, encoding::BASE64_PAD_PERMISSIVE;
115123
/// Base64 url, rfc4648 no padding (alphabet: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_).
116-
Base64Url, encoding::BASE64URL_NOPAD;
124+
Base64Url, encoding::BASE64URL_NOPAD, encoding::BASE64URL_NOPAD_PERMISSIVE;
117125
/// Base64 url, rfc4648 with padding (alphabet: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_).
118-
Base64UrlPad, encoding::BASE64URL_PAD;
126+
Base64UrlPad, encoding::BASE64URL_PAD, encoding::BASE64URL_PAD_PERMISSIVE;
119127
}
120128

121129
derive_base_x! {
122130
/// Base10 (alphabet: 0123456789).
123-
Base10, encoding::BASE10;
131+
Base10, encoding::BASE10, encoding::BASE10_PERMISSIVE;
124132
/// Base58 flicker (alphabet: 123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ).
125-
Base58Flickr, encoding::BASE58_FLICKR;
133+
Base58Flickr, encoding::BASE58_FLICKR, encoding::BASE58_FLICKR_PERMISSIVE;
126134
/// Base58 bitcoin (alphabet: 123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz).
127-
Base58Btc, encoding::BASE58_BITCOIN;
135+
Base58Btc, encoding::BASE58_BITCOIN, encoding::BASE58_BITCOIN_PERMISSIVE;
128136
}
129137

130138
/// Base36, [0-9a-z] no padding (alphabet: abcdefghijklmnopqrstuvwxyz0123456789).
@@ -136,10 +144,14 @@ impl BaseCodec for Base36Lower {
136144
base_x::encode(encoding::BASE36_LOWER, input.as_ref())
137145
}
138146

139-
fn decode<I: AsRef<str>>(input: I) -> Result<Vec<u8>> {
140-
// The input is case insensitive, hence lowercase it
141-
let lowercased = input.as_ref().to_ascii_lowercase();
142-
Ok(base_x::decode(encoding::BASE36_LOWER, &lowercased)?)
147+
fn decode<I: AsRef<str>>(input: I, strict: bool) -> Result<Vec<u8>> {
148+
if strict {
149+
Ok(base_x::decode(encoding::BASE36_LOWER, input.as_ref())?)
150+
} else {
151+
// The input is case insensitive, hence lowercase it
152+
let lowercased = input.as_ref().to_ascii_lowercase();
153+
Ok(base_x::decode(encoding::BASE36_LOWER_PERMISSIVE, &lowercased)?)
154+
}
143155
}
144156
}
145157

@@ -152,9 +164,13 @@ impl BaseCodec for Base36Upper {
152164
base_x::encode(encoding::BASE36_UPPER, input.as_ref())
153165
}
154166

155-
fn decode<I: AsRef<str>>(input: I) -> Result<Vec<u8>> {
156-
// The input is case insensitive, hence uppercase it
157-
let uppercased = input.as_ref().to_ascii_uppercase();
158-
Ok(base_x::decode(encoding::BASE36_UPPER, &uppercased)?)
167+
fn decode<I: AsRef<str>>(input: I, strict: bool) -> Result<Vec<u8>> {
168+
if strict {
169+
Ok(base_x::decode(encoding::BASE36_UPPER, input.as_ref())?)
170+
} else {
171+
// The input is case insensitive, hence uppercase it
172+
let uppercased = input.as_ref().to_ascii_uppercase();
173+
Ok(base_x::decode(encoding::BASE36_UPPER_PERMISSIVE, &uppercased)?)
174+
}
159175
}
160176
}

0 commit comments

Comments
 (0)