Python | Strings C de codificación dudosa | Serie 1

Uno puede convertir strings entre C y Python viceversa, pero la codificación C es de naturaleza dudosa o desconocida. Supongamos que se supone que un dato C dado es UTF-8, pero no se aplica estrictamente. Por lo tanto, es importante manejar este tipo de datos mal formados para que no bloquee Python ni destruya los datos de la string en el proceso.

Código n. ° 1: datos C y una función que ilustra el problema.

/* Some dubious string data (malformed UTF-8) */
const char* sdata = "Spicy Jalape\xc3\xb1o\xae";
int slen = 16;
/* Output character data */
void print_chars(char* s, int len)
{
    int n = 0;
    while (n < len) {
        printf("%2x ", (unsigned char)s[n]);
        n++;
    }
    printf("\n");
}

En el código anterior, la string sdata contiene una combinación de datos con formato incorrecto y UTF-8. Sin embargo, si un usuario llama print_chars(sdata, slen)en C, funciona bien.

Ahora supongamos que uno quiere convertir el contenido de sdata en una string de Python y luego pasar esa string a la print_chars() función a través de una extensión. El código que se muestra a continuación muestra la forma en que se conservan exactamente los datos originales aunque haya problemas de codificación.

Código #2:

/* Return the C string back to Python */
static PyObject *py_retstr(PyObject *self, PyObject *args)
{
    if (!PyArg_ParseTuple(args, ""))
    {
        return NULL;
    }
    return PyUnicode_Decode(sdata, slen, "utf-8", "surrogateescape");
}
  
/* Wrapper for the print_chars() function */
static PyObject *py_print_chars(PyObject *self, PyObject *args)
{
    PyObject *obj, *bytes;
    char *s = 0;
    Py_ssize_t len;
    if (!PyArg_ParseTuple(args, "U", &obj))
    {
        return NULL;
    }
    if ((bytes = PyUnicode_AsEncodedString(obj,
    "utf-8","surrogateescape"))
            == NULL)
    {
        return NULL;
    }
    PyBytes_AsStringAndSize(bytes, &s, &len);
    print_chars(s, len);
    Py_DECREF(bytes);
    Py_RETURN_NONE;
}

Código # 3: Usando el código anterior 2

s = retstr()
printf (s)
  
printf ("\n", print_chars(s))
'Spicy Jalapeño\udcae'

53 70 69 63 79 20 4a 61 6c 61 70 65 c3 b1 6f ae

Aquí, uno puede ver que la string con formato incorrecto se codificó en una string de Python sin errores y que cuando se pasó de nuevo a C, se convirtió de nuevo en una string de bytes que codificó exactamente los mismos bytes que la string de C original.

Publicación traducida automáticamente

Artículo escrito por manikachandna97 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *