extmod: Add ubinascii.unhexlify
This also pulls out hex_digit from py/lexer.c and makes unichar_hex_digit
This commit is contained in:
parent
97ce883217
commit
3ad94d6072
|
@ -13,3 +13,8 @@ Functions
|
||||||
.. function:: hexlify(data)
|
.. function:: hexlify(data)
|
||||||
|
|
||||||
Convert binary data to hexadecimal representation. Return bytes string.
|
Convert binary data to hexadecimal representation. Return bytes string.
|
||||||
|
|
||||||
|
.. function:: unhexlify(data)
|
||||||
|
|
||||||
|
Convert hexadecimal data to binary representation. Return bytes string.
|
||||||
|
(i.e. inverse of hexlify)
|
||||||
|
|
|
@ -35,6 +35,8 @@
|
||||||
#if MICROPY_PY_UBINASCII
|
#if MICROPY_PY_UBINASCII
|
||||||
|
|
||||||
STATIC mp_obj_t mod_binascii_hexlify(mp_uint_t n_args, const mp_obj_t *args) {
|
STATIC mp_obj_t mod_binascii_hexlify(mp_uint_t n_args, const mp_obj_t *args) {
|
||||||
|
// Second argument is for an extension to allow a separator to be used
|
||||||
|
// between values.
|
||||||
(void)n_args;
|
(void)n_args;
|
||||||
mp_buffer_info_t bufinfo;
|
mp_buffer_info_t bufinfo;
|
||||||
mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_READ);
|
mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_READ);
|
||||||
|
@ -58,10 +60,39 @@ STATIC mp_obj_t mod_binascii_hexlify(mp_uint_t n_args, const mp_obj_t *args) {
|
||||||
}
|
}
|
||||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_binascii_hexlify_obj, 1, 2, mod_binascii_hexlify);
|
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_binascii_hexlify_obj, 1, 2, mod_binascii_hexlify);
|
||||||
|
|
||||||
|
STATIC mp_obj_t mod_binascii_unhexlify(mp_obj_t data) {
|
||||||
|
mp_buffer_info_t bufinfo;
|
||||||
|
mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ);
|
||||||
|
|
||||||
|
if ((bufinfo.len & 1) != 0) {
|
||||||
|
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "odd-length string"));
|
||||||
|
}
|
||||||
|
vstr_t vstr;
|
||||||
|
vstr_init_len(&vstr, bufinfo.len / 2);
|
||||||
|
byte *in = bufinfo.buf, *out = (byte*)vstr.buf;
|
||||||
|
byte hex_byte = 0;
|
||||||
|
for (mp_uint_t i = bufinfo.len; i--;) {
|
||||||
|
byte hex_ch = *in++;
|
||||||
|
if (unichar_isxdigit(hex_ch)) {
|
||||||
|
hex_byte += unichar_xdigit_value(hex_ch);
|
||||||
|
} else {
|
||||||
|
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "non-hex digit found"));
|
||||||
|
}
|
||||||
|
if (i & 1) {
|
||||||
|
hex_byte <<= 4;
|
||||||
|
} else {
|
||||||
|
*out++ = hex_byte;
|
||||||
|
hex_byte = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_1(mod_binascii_unhexlify_obj, mod_binascii_unhexlify);
|
||||||
|
|
||||||
STATIC const mp_map_elem_t mp_module_binascii_globals_table[] = {
|
STATIC const mp_map_elem_t mp_module_binascii_globals_table[] = {
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_ubinascii) },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_ubinascii) },
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_hexlify), (mp_obj_t)&mod_binascii_hexlify_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_hexlify), (mp_obj_t)&mod_binascii_hexlify_obj },
|
||||||
// { MP_OBJ_NEW_QSTR(MP_QSTR_unhexlify), (mp_obj_t)&mod_binascii_unhexlify_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_unhexlify), (mp_obj_t)&mod_binascii_unhexlify_obj },
|
||||||
// { MP_OBJ_NEW_QSTR(MP_QSTR_a2b_base64), (mp_obj_t)&mod_binascii_a2b_base64_obj },
|
// { MP_OBJ_NEW_QSTR(MP_QSTR_a2b_base64), (mp_obj_t)&mod_binascii_a2b_base64_obj },
|
||||||
// { MP_OBJ_NEW_QSTR(MP_QSTR_b2a_base64), (mp_obj_t)&mod_binascii_b2a_base64_obj },
|
// { MP_OBJ_NEW_QSTR(MP_QSTR_b2a_base64), (mp_obj_t)&mod_binascii_b2a_base64_obj },
|
||||||
};
|
};
|
||||||
|
|
12
py/lexer.c
12
py/lexer.c
|
@ -261,16 +261,6 @@ STATIC const char *tok_kw[] = {
|
||||||
"__debug__",
|
"__debug__",
|
||||||
};
|
};
|
||||||
|
|
||||||
STATIC mp_uint_t hex_digit(unichar c) {
|
|
||||||
// c is assumed to be hex digit
|
|
||||||
mp_uint_t n = c - '0';
|
|
||||||
if (n > 9) {
|
|
||||||
n &= ~('a' - 'A');
|
|
||||||
n -= ('A' - ('9' + 1));
|
|
||||||
}
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is called with CUR_CHAR() before first hex digit, and should return with
|
// This is called with CUR_CHAR() before first hex digit, and should return with
|
||||||
// it pointing to last hex digit
|
// it pointing to last hex digit
|
||||||
// num_digits must be greater than zero
|
// num_digits must be greater than zero
|
||||||
|
@ -282,7 +272,7 @@ STATIC bool get_hex(mp_lexer_t *lex, mp_uint_t num_digits, mp_uint_t *result) {
|
||||||
if (!unichar_isxdigit(c)) {
|
if (!unichar_isxdigit(c)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
num = (num << 4) + hex_digit(c);
|
num = (num << 4) + unichar_xdigit_value(c);
|
||||||
}
|
}
|
||||||
*result = num;
|
*result = num;
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -127,6 +127,7 @@ bool unichar_isupper(unichar c);
|
||||||
bool unichar_islower(unichar c);
|
bool unichar_islower(unichar c);
|
||||||
unichar unichar_tolower(unichar c);
|
unichar unichar_tolower(unichar c);
|
||||||
unichar unichar_toupper(unichar c);
|
unichar unichar_toupper(unichar c);
|
||||||
|
mp_uint_t unichar_xdigit_value(unichar c);
|
||||||
mp_uint_t unichar_charlen(const char *str, mp_uint_t len);
|
mp_uint_t unichar_charlen(const char *str, mp_uint_t len);
|
||||||
#define UTF8_IS_NONASCII(ch) ((ch) & 0x80)
|
#define UTF8_IS_NONASCII(ch) ((ch) & 0x80)
|
||||||
#define UTF8_IS_CONT(ch) (((ch) & 0xC0) == 0x80)
|
#define UTF8_IS_CONT(ch) (((ch) & 0xC0) == 0x80)
|
||||||
|
|
|
@ -584,6 +584,7 @@ Q(sha256)
|
||||||
#if MICROPY_PY_UBINASCII
|
#if MICROPY_PY_UBINASCII
|
||||||
Q(ubinascii)
|
Q(ubinascii)
|
||||||
Q(hexlify)
|
Q(hexlify)
|
||||||
|
Q(unhexlify)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MICROPY_PY_MACHINE
|
#if MICROPY_PY_MACHINE
|
||||||
|
|
10
py/unicode.c
10
py/unicode.c
|
@ -169,3 +169,13 @@ unichar unichar_toupper(unichar c) {
|
||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mp_uint_t unichar_xdigit_value(unichar c) {
|
||||||
|
// c is assumed to be hex digit
|
||||||
|
mp_uint_t n = c - '0';
|
||||||
|
if (n > 9) {
|
||||||
|
n &= ~('a' - 'A');
|
||||||
|
n -= ('A' - ('9' + 1));
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
try:
|
||||||
|
import ubinascii as binascii
|
||||||
|
except ImportError:
|
||||||
|
import binascii
|
||||||
|
|
||||||
|
print(binascii.unhexlify(b'0001020304050607'))
|
||||||
|
print(binascii.unhexlify(b'08090a0b0c0d0e0f'))
|
||||||
|
print(binascii.unhexlify(b'7f80ff'))
|
||||||
|
print(binascii.unhexlify(b'313233344142434461626364'))
|
Loading…
Reference in New Issue