@@ -89,14 +89,114 @@ mp_obj_t mod_binascii_unhexlify(mp_obj_t data) {
8989}
9090MP_DEFINE_CONST_FUN_OBJ_1 (mod_binascii_unhexlify_obj , mod_binascii_unhexlify );
9191
92+ mp_obj_t mod_binascii_a2b_base64 (mp_obj_t data ) {
93+ mp_buffer_info_t bufinfo ;
94+ mp_get_buffer_raise (data , & bufinfo , MP_BUFFER_READ );
95+ if (bufinfo .len % 4 != 0 ) {
96+ nlr_raise (mp_obj_new_exception_msg (& mp_type_ValueError , "incorrect padding" ));
97+ }
98+
99+ vstr_t vstr ;
100+ byte * in = bufinfo .buf ;
101+ if (bufinfo .len == 0 ) {
102+ vstr_init_len (& vstr , 0 );
103+ }
104+ else {
105+ vstr_init_len (& vstr , ((bufinfo .len / 4 ) * 3 ) - ((in [bufinfo .len - 1 ] == '=' ) ? ((in [bufinfo .len - 2 ] == '=' ) ? 2 : 1 ) : 0 ));
106+ }
107+ byte * out = (byte * )vstr .buf ;
108+ for (mp_uint_t i = bufinfo .len ; i ; i -= 4 ) {
109+ char hold [4 ];
110+ for (int j = 4 ; j -- ;) {
111+ if (in [j ] >= 'A' && in [j ] <= 'Z' ) {
112+ hold [j ] = in [j ] - 'A' ;
113+ } else if (in [j ] >= 'a' && in [j ] <= 'z' ) {
114+ hold [j ] = in [j ] - 'a' + 26 ;
115+ } else if (in [j ] >= '0' && in [j ] <= '9' ) {
116+ hold [j ] = in [j ] - '0' + 52 ;
117+ } else if (in [j ] == '+' ) {
118+ hold [j ] = 62 ;
119+ } else if (in [j ] == '/' ) {
120+ hold [j ] = 63 ;
121+ } else if (in [j ] == '=' ) {
122+ if (j < 2 || i > 4 ) {
123+ nlr_raise (mp_obj_new_exception_msg (& mp_type_ValueError , "invalid padding" ));
124+ }
125+ hold [j ] = 64 ;
126+ } else {
127+ nlr_raise (mp_obj_new_exception_msg (& mp_type_ValueError , "invalid character" ));
128+ }
129+ }
130+ in += 4 ;
131+
132+ * out ++ = (hold [0 ]) << 2 | (hold [1 ]) >> 4 ;
133+ if (hold [2 ] != 64 ) {
134+ * out ++ = (hold [1 ] & 0x0F ) << 4 | hold [2 ] >> 2 ;
135+ if (hold [3 ] != 64 ) {
136+ * out ++ = (hold [2 ] & 0x03 ) << 6 | hold [3 ];
137+ }
138+ }
139+ }
140+ return mp_obj_new_str_from_vstr (& mp_type_bytes , & vstr );
141+ }
142+ MP_DEFINE_CONST_FUN_OBJ_1 (mod_binascii_a2b_base64_obj , mod_binascii_a2b_base64 );
143+
144+ mp_obj_t mod_binascii_b2a_base64 (mp_obj_t data ) {
145+ mp_buffer_info_t bufinfo ;
146+ mp_get_buffer_raise (data , & bufinfo , MP_BUFFER_READ );
147+
148+ vstr_t vstr ;
149+ vstr_init_len (& vstr , ((bufinfo .len != 0 ) ? (((bufinfo .len - 1 ) / 3 ) + 1 ) * 4 : 0 ) + 1 );
150+ byte * in = bufinfo .buf , * out = (byte * )vstr .buf ;
151+ for (mp_uint_t i = bufinfo .len ; i >= 3 ; i -= 3 ) {
152+ * out ++ = (in [0 ] & 0xFC ) >> 2 ;
153+ * out ++ = (in [0 ] & 0x03 ) << 4 | (in [1 ] & 0xF0 ) >> 4 ;
154+ * out ++ = (in [1 ] & 0x0F ) << 2 | (in [2 ] & 0xC0 ) >> 6 ;
155+ * out ++ = in [2 ] & 0x3F ;
156+ in += 3 ;
157+ }
158+ if (bufinfo .len % 3 != 0 ) {
159+ * out ++ = (in [0 ] & 0xFC ) >> 2 ;
160+ if (bufinfo .len % 3 == 2 ) {
161+ * out ++ = (in [0 ] & 0x03 ) << 4 | (in [1 ] & 0xF0 ) >> 4 ;
162+ * out ++ = (in [1 ] & 0x0F ) << 2 ;
163+ }
164+ else {
165+ * out ++ = (in [0 ] & 0x03 ) << 4 ;
166+ * out ++ = 64 ;
167+ }
168+ * out ++ = 64 ;
169+ }
170+ out = (byte * )vstr .buf ;
171+ for (mp_uint_t i = vstr .len - 1 ; i -- ;) {
172+ if (* out < 26 ) {
173+ * out += 'A' ;
174+ } else if (* out < 52 ) {
175+ * out += 'a' - 26 ;
176+ } else if (* out < 62 ) {
177+ * out += '0' - 52 ;
178+ } else if (* out == 62 ) {
179+ * out = '+' ;
180+ } else if (* out == 63 ) {
181+ * out = '/' ;
182+ } else {
183+ * out = '=' ;
184+ }
185+ out ++ ;
186+ }
187+ * out = '\n' ;
188+ return mp_obj_new_str_from_vstr (& mp_type_bytes , & vstr );
189+ }
190+ MP_DEFINE_CONST_FUN_OBJ_1 (mod_binascii_b2a_base64_obj , mod_binascii_b2a_base64 );
191+
92192#if MICROPY_PY_UBINASCII
93193
94194STATIC const mp_map_elem_t mp_module_binascii_globals_table [] = {
95195 { MP_OBJ_NEW_QSTR (MP_QSTR___name__ ), MP_OBJ_NEW_QSTR (MP_QSTR_ubinascii ) },
96196 { MP_OBJ_NEW_QSTR (MP_QSTR_hexlify ), (mp_obj_t )& mod_binascii_hexlify_obj },
97197 { MP_OBJ_NEW_QSTR (MP_QSTR_unhexlify ), (mp_obj_t )& mod_binascii_unhexlify_obj },
98- // { MP_OBJ_NEW_QSTR(MP_QSTR_a2b_base64), (mp_obj_t)&mod_binascii_a2b_base64_obj },
99- // { MP_OBJ_NEW_QSTR(MP_QSTR_b2a_base64), (mp_obj_t)&mod_binascii_b2a_base64_obj },
198+ { MP_OBJ_NEW_QSTR (MP_QSTR_a2b_base64 ), (mp_obj_t )& mod_binascii_a2b_base64_obj },
199+ { MP_OBJ_NEW_QSTR (MP_QSTR_b2a_base64 ), (mp_obj_t )& mod_binascii_b2a_base64_obj },
100200};
101201
102202STATIC MP_DEFINE_CONST_DICT (mp_module_binascii_globals , mp_module_binascii_globals_table );
0 commit comments