@@ -12,20 +12,31 @@ use crate::prelude::*;
12
12
/// RFC4648 encoding table
13
13
const RFC4648_ALPHABET : & ' static [ u8 ] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567" ;
14
14
15
+ /// Zbase encoding alphabet
16
+ const ZBASE_ALPHABET : & ' static [ u8 ] = b"ybndrfg8ejkmcpqxot1uwisza345h769" ;
17
+
15
18
/// RFC4648 decoding table
16
19
const RFC4648_INV_ALPHABET : [ i8 ; 43 ] = [
17
20
-1 , -1 , 26 , 27 , 28 , 29 , 30 , 31 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ,
18
21
9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 ,
19
22
] ;
20
23
24
+ /// Zbase decoding table
25
+ const ZBASE_INV_ALPHABET : [ i8 ; 43 ] = [
26
+ -1 , 18 , -1 , 25 , 26 , 27 , 30 , 29 , 7 , 31 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , 24 , 1 , 12 , 3 , 8 , 5 , 6 , 28 ,
27
+ 21 , 9 , 10 , -1 , 11 , 2 , 16 , 13 , 14 , 4 , 22 , 17 , 19 , -1 , 20 , 15 , 0 , 23 ,
28
+ ] ;
29
+
21
30
/// Alphabet used for encoding and decoding.
22
31
#[ derive( Copy , Clone ) ]
23
32
pub enum Alphabet {
24
33
/// RFC4648 encoding.
25
34
RFC4648 {
26
35
/// Whether to use padding.
27
36
padding : bool
28
- }
37
+ } ,
38
+ /// Zbase32 encoding.
39
+ ZBase32
29
40
}
30
41
31
42
impl Alphabet {
@@ -47,7 +58,10 @@ impl Alphabet {
47
58
return String :: from_utf8 ( ret) . expect ( "Invalid UTF-8" ) ;
48
59
}
49
60
ret
50
- }
61
+ } ,
62
+ Self :: ZBase32 => {
63
+ Self :: encode_data ( data, ZBASE_ALPHABET )
64
+ } ,
51
65
} ;
52
66
ret. truncate ( output_length) ;
53
67
@@ -72,6 +86,9 @@ impl Alphabet {
72
86
} ) ;
73
87
}
74
88
( & data[ ..unpadded_data_length] , RFC4648_INV_ALPHABET )
89
+ } ,
90
+ Self :: ZBase32 => {
91
+ ( data, ZBASE_INV_ALPHABET )
75
92
}
76
93
} ;
77
94
// If the string has more characters than are required to alphabet_encode the number of bytes
@@ -148,6 +165,44 @@ impl Alphabet {
148
165
mod tests {
149
166
use super :: * ;
150
167
168
+ const ZBASE32_TEST_DATA : & [ ( & str , & [ u8 ] ) ] = & [
169
+ ( "" , & [ ] ) ,
170
+ ( "yy" , & [ 0x00 ] ) ,
171
+ ( "oy" , & [ 0x80 ] ) ,
172
+ ( "tqrey" , & [ 0x8b , 0x88 , 0x80 ] ) ,
173
+ ( "6n9hq" , & [ 0xf0 , 0xbf , 0xc7 ] ) ,
174
+ ( "4t7ye" , & [ 0xd4 , 0x7a , 0x04 ] ) ,
175
+ ( "6im5sdy" , & [ 0xf5 , 0x57 , 0xbb , 0x0c ] ) ,
176
+ ( "ybndrfg8ejkmcpqxot1uwisza345h769" , & [ 0x00 , 0x44 , 0x32 , 0x14 , 0xc7 , 0x42 , 0x54 , 0xb6 ,
177
+ 0x35 , 0xcf , 0x84 , 0x65 , 0x3a , 0x56 , 0xd7 , 0xc6 ,
178
+ 0x75 , 0xbe , 0x77 , 0xdf ] )
179
+ ] ;
180
+
181
+ #[ test]
182
+ fn test_zbase32_encode ( ) {
183
+ for & ( zbase32, data) in ZBASE32_TEST_DATA {
184
+ assert_eq ! ( Alphabet :: ZBase32 . encode( data) , zbase32) ;
185
+ }
186
+ }
187
+
188
+ #[ test]
189
+ fn test_zbase32_decode ( ) {
190
+ for & ( zbase32, data) in ZBASE32_TEST_DATA {
191
+ assert_eq ! ( Alphabet :: ZBase32 . decode( zbase32) . unwrap( ) , data) ;
192
+ }
193
+ }
194
+
195
+ #[ test]
196
+ fn test_decode_wrong ( ) {
197
+ const WRONG_DATA : & [ & str ] = & [ "00" , "l1" , "?" , "=" ] ;
198
+ for & data in WRONG_DATA {
199
+ match Alphabet :: ZBase32 . decode ( data) {
200
+ Ok ( _) => assert ! ( false , "Data shouldn't be decodable" ) ,
201
+ Err ( _) => assert ! ( true ) ,
202
+ }
203
+ }
204
+ }
205
+
151
206
const RFC4648_NON_PADDED_TEST_VECTORS : & [ ( & [ u8 ] , & [ u8 ] ) ] = & [
152
207
( & [ 0xF8 , 0x3E , 0x7F , 0x83 , 0xE7 ] , b"7A7H7A7H" ) ,
153
208
( & [ 0x77 , 0xC1 , 0xF7 , 0x7C , 0x1F ] , b"O7A7O7A7" ) ,
0 commit comments