@@ -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