]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
After a brief conversation and code review with TP, adding two very
authorBarry Warsaw <barry@python.org>
Tue, 15 Aug 2000 06:07:13 +0000 (06:07 +0000)
committerBarry Warsaw <barry@python.org>
Tue, 15 Aug 2000 06:07:13 +0000 (06:07 +0000)
commonly used functions to convert an arbitrary binary string into
a hexadecimal digit representation and back again.  These are often
(and often differently) implemented in Python.  Best to have one
common fast implementation.  Specifically,

binascii_hexlify(): a.k.a. b2a_hex() to return the hex representation
of binary data.

binascii_unhexlify(): a.k.a. a2b_hex() to do the inverse conversion
(hex digits to binary data).  The argument must have an even length,
and must contain only hex digits, otherwise a TypeError is raised.

Modules/binascii.c

index 50f8b76044b5e46f3a90670338c3db6d242e8124..89ccc79c6eb040ff68bd1c0eea6d6934989194a1 100644 (file)
@@ -874,31 +874,135 @@ binascii_crc32(PyObject *self, PyObject *args)
        return Py_BuildValue("l", crc ^ 0xFFFFFFFFUL);
 }
 
+
+static PyObject *
+binascii_hexlify(PyObject *self, PyObject *args)
+{
+       char* argbuf;
+       int arglen;
+       PyObject *retval;
+       char* retbuf;
+       int i, j;
+
+       if (!PyArg_ParseTuple(args, "t#:b2a_hex", &argbuf, &arglen))
+               return NULL;
+
+       retval = PyString_FromStringAndSize(NULL, arglen*2);
+       if (!retval)
+               return NULL;
+       retbuf = PyString_AsString(retval);
+       if (!retbuf)
+               goto finally;
+
+       /* make hex version of string, taken from shamodule.c */
+       for (i=j=0; i < arglen; i++) {
+               char c;
+               c = (argbuf[i] >> 4) & 0xf;
+               c = (c>9) ? c+'a'-10 : c + '0';
+               retbuf[j++] = c;
+               c = argbuf[i] & 0xf;
+               c = (c>9) ? c+'a'-10 : c + '0';
+               retbuf[j++] = c;
+       }
+       return retval;
+
+  finally:
+       Py_DECREF(retval);
+       return NULL;
+}
+
+static char doc_hexlify[] =
+"b2a_hex(data) -> s; Hexadecimal representation of binary data.\n\
+\n\
+This function is also available as \"hexlify()\".";
+
+
+static int
+to_int(char c) 
+{
+       if (isdigit(c))
+               return c - '0';
+       else {
+               if (isupper(c))
+                       c = tolower(c);
+               if (c >= 'a' && c <= 'f')
+                       return c - 'a' + 10;
+       }
+       return -1;
+}
+
+
+static PyObject *
+binascii_unhexlify(PyObject *self, PyObject *args)
+{
+       char* argbuf;
+       int arglen;
+       PyObject *retval;
+       char* retbuf;
+       int i, j;
+
+       if (!PyArg_ParseTuple(args, "s#:a2b_hex", &argbuf, &arglen))
+               return NULL;
+
+       /* XXX What should we do about odd-lengthed strings?  Should we add
+        * an implicit leading zero, or a trailing zero?  For now, raise an
+        * exception.
+        */
+       if (arglen % 2) {
+               PyErr_SetString(PyExc_TypeError, "odd lengthed string");
+               return NULL;
+       }
+
+       retval = PyString_FromStringAndSize(NULL, (arglen/2));
+       if (!retval)
+               return NULL;
+       retbuf = PyString_AsString(retval);
+       if (!retbuf)
+               goto finally;
+
+       for (i=j=0; i < arglen; i += 2) {
+               int top = to_int(Py_CHARMASK(argbuf[i]));
+               int bot = to_int(Py_CHARMASK(argbuf[i+1]));
+               if (top == -1 || bot == -1) {
+                       PyErr_SetString(PyExc_TypeError,
+                                       "non-hexadecimal digit found");
+                       goto finally;
+               }
+               retbuf[j++] = (top << 4) + bot;
+       }
+       return retval;
+
+  finally:
+       Py_DECREF(retval);
+       return NULL;
+}
+
+static char doc_unhexlify[] =
+"a2b_hex(hexstr) -> s; Binary data of hexadecimal representation.\n\
+\n\
+hexstr must contain an even number of hex digits (upper or lower case).\n\
+This function is also available as \"unhexlify()\"";
+
+
 /* List of functions defined in the module */
 
 static struct PyMethodDef binascii_module_methods[] = {
-       {"a2b_uu",              binascii_a2b_uu,        
-        METH_VARARGS,  doc_a2b_uu},
-       {"b2a_uu",              binascii_b2a_uu,        
-        METH_VARARGS,  doc_b2a_uu},
-       {"a2b_base64",          binascii_a2b_base64,    
-        METH_VARARGS,
-        doc_a2b_base64},
-       {"b2a_base64",          binascii_b2a_base64,    
-        METH_VARARGS, doc_b2a_base64},
-       {"a2b_hqx",             binascii_a2b_hqx,       
-        METH_VARARGS, doc_a2b_hqx},
-       {"b2a_hqx",             binascii_b2a_hqx,       
-        METH_VARARGS, doc_b2a_hqx},
-       {"rlecode_hqx",         binascii_rlecode_hqx,   
-        METH_VARARGS, doc_rlecode_hqx},
-       {"rledecode_hqx",       binascii_rledecode_hqx, 
-        METH_VARARGS, doc_rledecode_hqx},
-       {"crc_hqx",             binascii_crc_hqx,       
-        METH_VARARGS,  doc_crc_hqx},
-       {"crc32",               binascii_crc32,         
-        METH_VARARGS, doc_crc32},
-       {NULL,                  NULL}           /* sentinel */
+       {"a2b_uu",     binascii_a2b_uu,     METH_VARARGS, doc_a2b_uu},
+       {"b2a_uu",     binascii_b2a_uu,     METH_VARARGS, doc_b2a_uu},
+       {"a2b_base64", binascii_a2b_base64, METH_VARARGS, doc_a2b_base64},
+       {"b2a_base64", binascii_b2a_base64, METH_VARARGS, doc_b2a_base64},
+       {"a2b_hqx",    binascii_a2b_hqx,    METH_VARARGS, doc_a2b_hqx},
+       {"b2a_hqx",    binascii_b2a_hqx,    METH_VARARGS, doc_b2a_hqx},
+       {"b2a_hex",    binascii_hexlify,    METH_VARARGS, doc_hexlify},
+       {"a2b_hex",    binascii_unhexlify,  METH_VARARGS, doc_unhexlify},
+       {"hexlify",    binascii_hexlify,    METH_VARARGS, doc_hexlify},
+       {"unhexlify",  binascii_unhexlify,  METH_VARARGS, doc_unhexlify},
+       {"rlecode_hqx",   binascii_rlecode_hqx, METH_VARARGS, doc_rlecode_hqx},
+       {"rledecode_hqx", binascii_rledecode_hqx, METH_VARARGS,
+        doc_rledecode_hqx},
+       {"crc_hqx",    binascii_crc_hqx,    METH_VARARGS, doc_crc_hqx},
+       {"crc32",      binascii_crc32,      METH_VARARGS, doc_crc32},
+       {NULL, NULL}                         /* sentinel */
 };