@@ -12,20 +12,31 @@ use crate::prelude::*;
1212/// RFC4648 encoding table
1313const RFC4648_ALPHABET : & ' static [ u8 ] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567" ;
1414
15+ /// Zbase encoding alphabet
16+ const ZBASE_ALPHABET : & ' static [ u8 ] = b"ybndrfg8ejkmcpqxot1uwisza345h769" ;
17+
1518/// RFC4648 decoding table
1619const RFC4648_INV_ALPHABET : [ i8 ; 43 ] = [
1720 -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 ,
1821 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 ,
1922] ;
2023
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+
2130/// Alphabet used for encoding and decoding.
2231#[ derive( Copy , Clone ) ]
2332pub enum Alphabet {
2433 /// RFC4648 encoding.
2534 RFC4648 {
2635 /// Whether to use padding.
2736 padding : bool
28- }
37+ } ,
38+ /// Zbase32 encoding.
39+ ZBase32
2940}
3041
3142impl Alphabet {
@@ -48,7 +59,10 @@ impl Alphabet {
4859 return String :: from_utf8 ( ret) . expect ( "Invalid UTF-8" ) ;
4960 }
5061 ret
51- }
62+ } ,
63+ Self :: ZBase32 => {
64+ Self :: encode_data ( data, ZBASE_ALPHABET )
65+ } ,
5266 } ;
5367 ret. truncate ( output_length) ;
5468
@@ -73,6 +87,9 @@ impl Alphabet {
7387 } ) ;
7488 }
7589 ( & data[ ..unpadded_data_length] , RFC4648_INV_ALPHABET )
90+ } ,
91+ Self :: ZBase32 => {
92+ ( data, ZBASE_INV_ALPHABET )
7693 }
7794 } ;
7895 // If the string has more characters than are required to alphabet_encode the number of bytes
@@ -150,6 +167,44 @@ impl Alphabet {
150167mod tests {
151168 use super :: * ;
152169
170+ const ZBASE32_TEST_DATA : & [ ( & str , & [ u8 ] ) ] = & [
171+ ( "" , & [ ] ) ,
172+ ( "yy" , & [ 0x00 ] ) ,
173+ ( "oy" , & [ 0x80 ] ) ,
174+ ( "tqrey" , & [ 0x8b , 0x88 , 0x80 ] ) ,
175+ ( "6n9hq" , & [ 0xf0 , 0xbf , 0xc7 ] ) ,
176+ ( "4t7ye" , & [ 0xd4 , 0x7a , 0x04 ] ) ,
177+ ( "6im5sdy" , & [ 0xf5 , 0x57 , 0xbb , 0x0c ] ) ,
178+ ( "ybndrfg8ejkmcpqxot1uwisza345h769" , & [ 0x00 , 0x44 , 0x32 , 0x14 , 0xc7 , 0x42 , 0x54 , 0xb6 ,
179+ 0x35 , 0xcf , 0x84 , 0x65 , 0x3a , 0x56 , 0xd7 , 0xc6 ,
180+ 0x75 , 0xbe , 0x77 , 0xdf ] )
181+ ] ;
182+
183+ #[ test]
184+ fn test_zbase32_encode ( ) {
185+ for & ( zbase32, data) in ZBASE32_TEST_DATA {
186+ assert_eq ! ( Alphabet :: ZBase32 . encode( data) , zbase32) ;
187+ }
188+ }
189+
190+ #[ test]
191+ fn test_zbase32_decode ( ) {
192+ for & ( zbase32, data) in ZBASE32_TEST_DATA {
193+ assert_eq ! ( Alphabet :: ZBase32 . decode( zbase32) . unwrap( ) , data) ;
194+ }
195+ }
196+
197+ #[ test]
198+ fn test_decode_wrong ( ) {
199+ const WRONG_DATA : & [ & str ] = & [ "00" , "l1" , "?" , "=" ] ;
200+ for & data in WRONG_DATA {
201+ match Alphabet :: ZBase32 . decode ( data) {
202+ Ok ( _) => assert ! ( false , "Data shouldn't be decodable" ) ,
203+ Err ( _) => assert ! ( true ) ,
204+ }
205+ }
206+ }
207+
153208 const RFC4648_NON_PADDED_TEST_VECTORS : & [ ( & [ u8 ] , & [ u8 ] ) ] = & [
154209 ( & [ 0xF8 , 0x3E , 0x7F , 0x83 , 0xE7 ] , b"7A7H7A7H" ) ,
155210 ( & [ 0x77 , 0xC1 , 0xF7 , 0x7C , 0x1F ] , b"O7A7O7A7" ) ,
0 commit comments