bpo-32147: Improved perfomance of binascii.unhexlify(). (GH-4586)
This commit is contained in:
parent
19e7d48ce8
commit
6b5df906af
|
@ -198,6 +198,11 @@ class BinASCIITest(unittest.TestCase):
|
||||||
self.assertEqual(s, u)
|
self.assertEqual(s, u)
|
||||||
self.assertRaises(binascii.Error, binascii.a2b_hex, t[:-1])
|
self.assertRaises(binascii.Error, binascii.a2b_hex, t[:-1])
|
||||||
self.assertRaises(binascii.Error, binascii.a2b_hex, t[:-1] + b'q')
|
self.assertRaises(binascii.Error, binascii.a2b_hex, t[:-1] + b'q')
|
||||||
|
self.assertRaises(binascii.Error, binascii.a2b_hex, bytes([255, 255]))
|
||||||
|
self.assertRaises(binascii.Error, binascii.a2b_hex, b'0G')
|
||||||
|
self.assertRaises(binascii.Error, binascii.a2b_hex, b'0g')
|
||||||
|
self.assertRaises(binascii.Error, binascii.a2b_hex, b'G0')
|
||||||
|
self.assertRaises(binascii.Error, binascii.a2b_hex, b'g0')
|
||||||
|
|
||||||
# Confirm that b2a_hex == hexlify and a2b_hex == unhexlify
|
# Confirm that b2a_hex == hexlify and a2b_hex == unhexlify
|
||||||
self.assertEqual(binascii.hexlify(self.type2test(s)), t)
|
self.assertEqual(binascii.hexlify(self.type2test(s)), t)
|
||||||
|
|
|
@ -460,6 +460,7 @@ Michael Farrell
|
||||||
Troy J. Farrell
|
Troy J. Farrell
|
||||||
Jim Fasarakis-Hilliard
|
Jim Fasarakis-Hilliard
|
||||||
Mark Favas
|
Mark Favas
|
||||||
|
Sergey Fedoseev
|
||||||
Boris Feld
|
Boris Feld
|
||||||
Thomas Fenzl
|
Thomas Fenzl
|
||||||
Niels Ferguson
|
Niels Ferguson
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
:func:`binascii.unhexlify` is now up to 2 times faster.
|
||||||
|
Patch by Sergey Fedoseev.
|
|
@ -1130,21 +1130,6 @@ binascii_hexlify_impl(PyObject *module, Py_buffer *data)
|
||||||
return _Py_strhex_bytes((const char *)data->buf, data->len);
|
return _Py_strhex_bytes((const char *)data->buf, data->len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
to_int(int c)
|
|
||||||
{
|
|
||||||
if (Py_ISDIGIT(c))
|
|
||||||
return c - '0';
|
|
||||||
else {
|
|
||||||
if (Py_ISUPPER(c))
|
|
||||||
c = Py_TOLOWER(c);
|
|
||||||
if (c >= 'a' && c <= 'f')
|
|
||||||
return c - 'a' + 10;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
binascii.a2b_hex
|
binascii.a2b_hex
|
||||||
|
|
||||||
|
@ -1187,9 +1172,9 @@ binascii_a2b_hex_impl(PyObject *module, Py_buffer *hexstr)
|
||||||
retbuf = PyBytes_AS_STRING(retval);
|
retbuf = PyBytes_AS_STRING(retval);
|
||||||
|
|
||||||
for (i=j=0; i < arglen; i += 2) {
|
for (i=j=0; i < arglen; i += 2) {
|
||||||
int top = to_int(Py_CHARMASK(argbuf[i]));
|
unsigned int top = _PyLong_DigitValue[Py_CHARMASK(argbuf[i])];
|
||||||
int bot = to_int(Py_CHARMASK(argbuf[i+1]));
|
unsigned int bot = _PyLong_DigitValue[Py_CHARMASK(argbuf[i+1])];
|
||||||
if (top == -1 || bot == -1) {
|
if (top >= 16 || bot >= 16) {
|
||||||
PyErr_SetString(Error,
|
PyErr_SetString(Error,
|
||||||
"Non-hexadecimal digit found");
|
"Non-hexadecimal digit found");
|
||||||
goto finally;
|
goto finally;
|
||||||
|
@ -1218,19 +1203,6 @@ binascii_unhexlify_impl(PyObject *module, Py_buffer *hexstr)
|
||||||
return binascii_a2b_hex_impl(module, hexstr);
|
return binascii_a2b_hex_impl(module, hexstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const int table_hex[128] = {
|
|
||||||
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
|
|
||||||
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
|
|
||||||
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
|
|
||||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1, -1,-1,-1,-1,
|
|
||||||
-1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
|
|
||||||
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
|
|
||||||
-1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
|
|
||||||
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1
|
|
||||||
};
|
|
||||||
|
|
||||||
#define hexval(c) table_hex[(unsigned int)(c)]
|
|
||||||
|
|
||||||
#define MAXLINESIZE 76
|
#define MAXLINESIZE 76
|
||||||
|
|
||||||
|
|
||||||
|
@ -1293,9 +1265,9 @@ binascii_a2b_qp_impl(PyObject *module, Py_buffer *data, int header)
|
||||||
(ascii_data[in+1] >= 'a' && ascii_data[in+1] <= 'f') ||
|
(ascii_data[in+1] >= 'a' && ascii_data[in+1] <= 'f') ||
|
||||||
(ascii_data[in+1] >= '0' && ascii_data[in+1] <= '9'))) {
|
(ascii_data[in+1] >= '0' && ascii_data[in+1] <= '9'))) {
|
||||||
/* hexval */
|
/* hexval */
|
||||||
ch = hexval(ascii_data[in]) << 4;
|
ch = _PyLong_DigitValue[ascii_data[in]] << 4;
|
||||||
in++;
|
in++;
|
||||||
ch |= hexval(ascii_data[in]);
|
ch |= _PyLong_DigitValue[ascii_data[in]];
|
||||||
in++;
|
in++;
|
||||||
odata[out++] = ch;
|
odata[out++] = ch;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue