Transmission bytearray from Python to C and return it

c, python

Solution

You don't need build an extension module to do this quickly, you can use NumPy. But for your question, you need some c code like this:

#include <Python.h>
#include <stdlib.h> 

static PyObject * fast_xor(PyObject* self, PyObject* args)
{
    const char* str;
    char * buf;
    Py_ssize_t count;
    PyObject * result;
    int i;

    if (!PyArg_ParseTuple(args, "s#", &str, &count))
    {
        return NULL;
    }

    buf = (char *)malloc(count);

    for(i=0;i<count;i++)
    {
        buf[i]=str[i] ^ 55;
    }

    result = Py_BuildValue("s#", buf, count);
    free(buf);
    return result;
}

You can't change the content of string object, because string in Python is immutable. You can use "s#" to get the `char *` pointer and the buffer length.

If you can use NumPy:

In [1]: import fastxor

In [2]: a = "abcdsafasf12q423\0sdfasdf"

In [3]: fastxor.fast_xor(a)
Out[3]: 'VUTSDVQVDQ\x06\x05F\x03\x05\x047DSQVDSQ'


In [5]: import numpy as np

In [6]: (np.frombuffer(a, np.int8)^55).tostring()
Out[6]: 'VUTSDVQVDQ\x06\x05F\x03\x05\x047DSQVDSQ'

In [7]: a = a*10000

In [8]: %timeit fastxor.fast_xor(a)
1000 loops, best of 3: 877 us per loop

In [15]: %timeit (np.frombuffer(a, np.int8)^55).tostring()
1000 loops, best of 3: 1.15 ms per loop

Problem

I need fast processing of XOR bytearray, In a variant on Python ``` for i in range(len(str1)): str1[i]=str1[i] ^ 55 ``` works very slow I wrote this module in C. I know C language very badly, before I on it wrote nothing. In a variant ``` PyArg_ParseTuple (args, "s", &str)) ``` everything works as expected, but I need to use instead of s s* because elements can contain embeded null, but if I change s to s* when calling python crash ``` PyArg_ParseTuple (args, "s*", &str)) // crash ``` Maybe some beginner like me want to use my example as a start to write something of his own, so bring all the information to be used in this example on Windows. Parsing arguments and building values on page http://docs.python.org/dev/c-api/arg.html test_xor.c ``` #include <Python.h> static PyObject* fast_xor(PyObject* self, PyObject* args) { const char* str ; int i; if (!PyArg_ParseTuple(args, "s", &str)) return NULL; for(i=0;i<sizeof(str);i++) {str[i]^=55;}; return Py_BuildValue("s", str); } static PyMethodDef fastxorMethods[] = { {"fast_xor", fast_xor, METH_VARARGS, "fast_xor desc"}, {NULL, NULL, 0, NULL} }; PyMODINIT_FUNC initfastxor(void) { (void) Py_InitModule("fastxor", fastxorMethods); } ``` test_xor.py ``` import fastxor a=fastxor.fast_xor("World") # it works with s instead s* print a a=fastxor.fast_xor("Wo\0rld") # It does not work with s instead s* ``` compile.bat ``` rem use http://bellard.org/tcc/ tiny_impdef.exe C:\Python26\python26.dll tcc -shared test_xor.c python26.def -IC:\Python26\include -LC:\Python26\libs -ofastxor.pyd test_xor.py ```

Original source