Python对short进行字节操作,而不是int

问题描述 投票:1回答:2

如何用Python编写以下C程序?问题是Python认为crcint,而不是short,因此结果是完全废话……

unsigned short special_crc16(volatile unsigned char *sbuf,unsigned int len){
    unsigned short crc=0xFFFF;

    while(len){
        crc=(unsigned char)(crc >> 8) | (crc << 8);
        crc^=(unsigned char) *sbuf;
        crc^=(unsigned char)(crc & 0xff) >> 4;
        crc^=(crc << 8) << 4;
        crc^=((crc & 0xff) << 4) << 1;
        len--;
        sbuf++;
    }
    return crc;
}

输入:8C 4C预期输出:CA B2

我的Python 3尝试:

def compute(data, datalen):
    crc=0xFFFF
    for i in range(0, datalen):
        crc = (crc >> 8) | (crc << 8)
        crc = crc ^ data[i]
        crc = crc ^ ((crc & 0xff) >> 4)
        crc = crc ^ ((crc << 8) << 4)
        crc = crc ^ (((crc & 0xff) << 4)<<1)

    return crc

返回FFFF00F030C2B2 ...

谢谢!

python python-3.x byte crc short
2个回答
0
投票

[我找到了一个解决方案:在int上工作,但是执行0x0000FFFF仅考虑前2个字节并模拟一个short。

还好吗?

def compute(data, datalen):
    crc=0x0000FFFF
    for i in range(0, datalen):
        crc = ((crc >> 8) & 0x0000ffff) | ((crc << 8) & 0x0000ffff)
        crc = crc ^ data[i]
        crc = crc ^ (((crc & 0xff) >> 4) & 0x0000ffff)
        crc = crc ^ ((crc << 12) & 0x0000ffff)
        crc = crc ^ (((crc & 0xff) << 5) & 0x0000ffff)

    return crc

0
投票

您总是可以将自己的类滚动为16位int。显然,并非所有这些方法都需要针对您的情况编写,我也省略了一些。

class UShort:
    def __init__(self, x):
        self._x = int(x) & 0xffff

    def __repr__(self):
        return '<UShort {}>'.format(self._x)

    @classmethod
    def to_short(cls, x):
        return cls(int(x) & 0xffff)

    @property
    def hex(self):
        return hex(self._x)

    def __add__(self, other): return self.to_short(self._x + self.to_short(other)._x)
    def __sub__(self, other): return self.to_short(self._x - self.to_short(other)._x)
    def __mul__(self, other): return self.to_short(self._x * self.to_short(other)._x)
    def __div__(self, other): return self.to_short(self._x / self.to_short(other)._x)
    def __mod__(self, other): return self.to_short(self._x % self.to_short(other)._x)
    def __pow__(self, other): return self.to_short(self._x ** self.to_short(other)._x)
    def __and__(self, other): return self.to_short(self._x & self.to_short(other)._x)
    def __xor__(self, other): return self.to_short(self._x ^ self.to_short(other)._x)
    def __or__(self, other): return self.to_short(self._x | self.to_short(other)._x)
    def __lshift__(self, other): return self.to_short(self._x << self.to_short(other)._x)
    def __rshift__(self, other): return self.to_short(self._x >> self.to_short(other)._x)
    def __radd__(self, other): return self.to_short(self.to_short(other)._x + self._x)
    def __rsub__(self, other): return self.to_short(self.to_short(other)._x - self._x)
    def __rmul__(self, other): return self.to_short(self.to_short(other)._x * self._x)
    def __rdiv__(self, other): return self.to_short(self.to_short(other)._x / self._x)
    def __rmod__(self, other): return self.to_short(self.to_short(other)._x % self._x)
    def __rpow__(self, other): return self.to_short(self.to_short(other)._x ** self._x)
    def __rand__(self, other): return self.to_short(self.to_short(other)._x & self._x)
    def __rxor__(self, other): return self.to_short(self.to_short(other)._x ^ self._x)
    def __ror__(self, other): return self.to_short(self.to_short(other)._x | self._x)
    def __rlshift__(self, other): return self.to_short(self.to_short(other)._x << self._x)
    def __rrshift__(self, other): return self.to_short(self.to_short(other)._x >> self._x)
    def __int__(self): return int(self._x)
    def __float__(self): return float(self._x)
    def __neg__(self): return self.to_short(self._x.__neg__())
    def __pos__(self): return self
    def __abs__(self): return self
    def __invert__(self): return self.to_short(self._x.__invert__())

然后修改您的计算机以使用新的类。

def compute(data, datalen):
    crc=UShort(0xFFFF)
    for i in range(0, datalen):
        crc = (crc >> 8) | (crc << 8)
        crc = crc ^ data[i]
        crc = crc ^ ((crc & 0xff) >> 4)
        crc = crc ^ ((crc << 8) << 4)
        crc = crc ^ (((crc & 0xff) << 4)<<1)

    return crc.hex

data = [0x8c, 0x4c]
compute(data, 2)
# returns:
'0xcab2'

推荐问答