C endianness(存储没有交换的python对象)

时间:2017-03-26 07:50:29

标签: c python-2.7

我想编写从python传递的十六进制字符串,因为它在C中的磁盘上。

我的问题是这些值以小端存储,并且值被交换。

示例:

如果我传递一个PyObject,即“abcdef12345123”,它应该在磁盘上写入给定的偏移量,即“abcdef12345123”

以下是此代码的示例代码和结果。

示例代码

static PyObject *
py_corrupt_disk_object(PyObject *self, PyObject *args)
{

        int size, optype, fixcrc;
        long offset;
        PyObject *baddr;
        char *op_value = NULL;

        if (!PyArg_ParseTuple(args,"Oliisi", &baddr, &offset, &size, &optype,
            &op_value,&fixcrc))
                Py_RETURN_NONE;

        d_locn_t locn = {};
        locn.idx.devid  = ((struct py_ifs_baddr*)baddr)->baddr.devid;
        locn.idx.drive  = ((struct py_ifs_baddr*)baddr)->baddr.drive;
        locn.idx.subidx = ((struct py_ifs_baddr*)baddr)->baddr._subblk;
        locn.idx.index  = ((struct py_ifs_baddr*)baddr)->baddr._block;

        d_print("Printing args in py_corrupt_disk_object: \n");
        d_print("offset %lu \n",offset);
        d_print("fixcrc %d \n",fixcrc);
        d_print("size %d \n",size);
        d_print("optype %d \n",optype);
        d_print("op_value %s \n",op_value);


        d_cpr_write(&locn, offset, size, optype, op_value, fixcrc);
        Py_RETURN_NONE;
}


PyObject*
d_cpr_write(d_locn_t *locn, int offset, int size, int optype, char *op_value, int fixcrc)
{

        cpr_obj* obj = NULL;
        struct po_typeinfo *tinfo = NULL;
        int obj_size = 0;
        d_print("The Values inside d_cpr_write():\n");
        d_print("offset %d \n",offset);
        d_print("fixcrc %d \n",fixcrc);
        d_print("size %d \n",size);
        d_print("optype %d \n",optype);
        d_print("op_value %s \n",op_value);


        if (locn->idx.subidx & BADDR_SIZE_512) {
                obj_size = BUFFER_512;
                tinfo = find_object('i');
                if (locn_iaddr_to_linsnap(locn) != d_OK) {
                        d_log(d_ERR, "lin snap conversion failed\n");
                        Py_RETURN_NONE;
                }
                locn->flags |= DLFLAG_HASXIADDRHINT;
                locn->xiaddrhint = d_index_to_baddr(locn->idx);
        } else {
                obj_size = BUFFER_8192;
                tinfo = find_object('b');
        }

        if (tinfo == NULL) {
                d_log(d_ERR, "Only Object i or b supported\n");
                Py_RETURN_NONE;
        }

        obj = alloc_objarg();

        // create cpr object
        obj->tinfo = tinfo;
        obj->locn = *locn;

        unsigned char *buff = NULL;
        if (!(buff = alloca(obj_size))) {
                d_log(d_ERR, "buffer allocation failed\n");
                Py_RETURN_NONE;
        }

        int index, xfered, bit_offset;

        if ((xfered = (*obj->tinfo->read)(&obj->locn, buff, obj_size)) < 0) {
                d_log(d_ERR, "read failed %d\n", xfered);
                Py_RETURN_NONE;
        }

        if (obj->tinfo->insane != NULL) {
                if ((*obj->tinfo->insane)(&obj->locn, buff, obj_size, 0) < 0) {
                        d_log(d_ERR, "%c object sanity check failed\n",
                            obj->tinfo->type);
                        Py_RETURN_NONE;
                }
        }

       d_print("Entering optype\n");
        if (optype == 2) { //overwrite
                unsigned long opval = strtol(op_value, NULL, 16);
                d_print("after rev =%ld ", opval);
                memcpy(&buff[offset], &opval, sizeof(opval));

         }//End of overwrite
        if (fixcrc)
                obj->locn.flags |= DLFLAG_WRITE_CRC;

        if (!obj->tinfo->write) {
                d_log(d_ERR, "no write function supported\n");
                Py_RETURN_NONE;
        }

        if ((xfered = (*obj->tinfo->write)(&obj->locn, buff, obj_size)) < 0) {
                d_log(d_ERR, "write failed %d\n", xfered);
                Py_RETURN_NONE;
        }

        Py_RETURN_NONE;
}

结果/输出:

./python inject_failures.py --optype=add --fixcrc=1 --object=baddr  --baddr=2,3,773463552:512  --offset=16 --mirror=1  --op_value='abcdef12345123' --size=8

> /usr/local_qa/bin/isi_corrupt.py(848)main()

-> if 'add' in options.optype and options.op_value is None:
(Pdb) c

> /usr/local_qa/bin/ inject_failures.py (185)corrupt_diskobject()

-> logging.info("Corrupting disk object %s at %s", obj_type, disk_object)
(Pdb) c

在py_corrupt_disk_object中打印args:

偏移16

fixcrc 1

8号

optype 2

op_value abcdef12345123

d_cpr_write()中的值:

偏移16

fixcrc 1

8号

optype 2

op_value abcdef12345123

输入optype

在rev = 48358647703818531

之后

问题:

我可以看到数据写得不正确(如果我使用hexdump检查)

在:

<00> 00000010 e0 01 04 00 01 00 00 00 02 00 00 00 00 00 00 00 | ................ |

之后:

<00> 00000010 23 51 34 12 ef cd ab 00 02 00 00 00 00 00 00 00 |#Q4 ............. | ==&GT; 23513412 efcdab00

C-问题:

  1. 有没有办法可以停止这种转换并在C中写入值,从输出看起来就像我们交换字节然后以小端顺序写入磁盘?我正在做一个memcpy()可能有更简单的东西可以帮助我们编写数据而无需交换?

  2. op_value始终为14位或7个字节。如何复制磁盘上的7个字节。 (我是C的新手,所以在提供建议的同时考虑这一点)

  3. Python问题

    1. 我是否可以在python层中注意避免这种交换或任何其他关于如何解决这个问题的建议(我在Python 2.7和Linux上)。

1 个答案:

答案 0 :(得分:1)

发生的事情很简单:你得到一个字符串,你写了一个长篇:

unsigned long opval = strtol(op_value, NULL, 16);

总之,字节被交换;在字符串中他们不是。所以写一个字符串,每一个都没关系。

<小时/> 所以你想要一个长的,存储的字节反转,哪个是正确的,与非反转的字节一起存储?问题就是原因,因为现在没有任何程序可以再读回来,但唉,这样做的代码是:

if (optype == 2) {
    unsigned long opval = strtol(op_value, NULL, 16);
    char *longval, *bufp;
    longval= (char *)&opval;
    bufp= buff;
    for (int i=sizeof(long)-1; i>=0; i--)
        *bufp++ = *(longval+i);
 }