3

我正在尝试将这段代码从 C 移植到 python。即使它是相同的代码,输出也不同。

这是有效的代码的 C 版本:

int main(void)
{

uint8_t pac[] = {0x033,0x55,0x22,0x65,0x76};
uint8_t len = 5;
uint8_t chan = 0x64;

btLeWhiten(pac, len, chan);

    for(int i = 0;i<=len;i++)
    {
        printf("Whiten %02d \r\n",pac[i]);
     }

   while(1)
   {    

   }

  return 0;
  }



void btLeWhiten(uint8_t* data, uint8_t len, uint8_t whitenCoeff)
{

uint8_t  m;

while(len--){   
    for(m = 1; m; m <<= 1){

        if(whitenCoeff & 0x80){

            whitenCoeff ^= 0x11;
            (*data) ^= m;
        }
        whitenCoeff <<= 1;

    }
    data++;
  }
}

我目前在 Python 中拥有的是:

def whiten(data, len, whitenCoeff):
    idx = len 
    while(idx > 0):
        m = 0x01
        for i in range(0,8):
            if(whitenCoeff & 0x80):
                whitenCoeff ^= 0x11
                data[len - idx -1 ] ^= m
                whitenCoeff <<= 1 
                m  <<= 0x01

        idx = idx - 1


pac = [0x33,0x55,0x22,0x65,0x76]
len = 5
chan = 0x64

def main():

whiten(pac,5,chan)
print pac


if __name__=="__main__":
    main()

我看到的问题是 whitenCoeff 在 C 代码段中始终保持 8 位,但在每次循环传递时它在 Python 中大于 8 位。

4

5 回答 5

1

在 C 中,您将数据从 0 写入 len-1,但在 Python 中,您将数据从 -1 写入 len-2。从此行中删除 -1:

data[len - idx -1 ] ^= m

像这样

data[len - idx] ^= m

您还需要将此行放在 if 之外:

whitenCoeff <<= 1 
于 2016-09-05T21:10:19.497 回答
1

你还有几个问题。

  1. whitenCoeff <<= 1;if位于C 代码中的块之外,但它if位于 Python 代码中的块之内。
  2. data[len - idx -1 ] ^= m没有正确翻译,它从 C 代码向后工作。

此代码产生与 C 代码相同的输出:

def whiten(data, whitenCoeff):
    for index in range(len(data)):
        for i in range(8):
            if (whitenCoeff & 0x80):
                whitenCoeff ^= 0x11
                data[index] ^= (1 << i)

            whitenCoeff = (whitenCoeff << 1) & 0xff

    return data

if __name__=="__main__":
    print whiten([0x33,0x55,0x22,0x65,0x76], 0x64)
于 2016-09-05T21:20:42.947 回答
1

whitenCoeff <<= 1因为是 8 位数据,所以 C 中的 0 会在一段时间后变为 0。

在python中,没有这样的限制,所以你必须写:

whitenCoeff = (whitenCoeff<<1) & 0xFF

屏蔽更高的位。

(不要忘记检查数组边界上的 vz0 备注)

另外还有一个缩进问题。

重写的代码给出了相同的结果:

def whiten(data, whitenCoeff):
    idx = len(data)
    while(idx > 0):
        m = 0x01
        for i in range(0,8):
            if(whitenCoeff & 0x80):
                whitenCoeff ^= 0x11
                data[-idx] ^= m
            whitenCoeff = (whitenCoeff<<1) & 0xFF
            m  <<= 0x01

        idx = idx - 1


pac = [0x33,0x55,0x22,0x65,0x76]
chan = 0x64

def main():

    whiten(pac,chan)
    print(pac)


if __name__=="__main__":
    main()

稍微跑题:注意C版已经有问题了:

for(int i = 0;i<=len;i++)

应该

for(int i = 0;i<len;i++)
于 2016-09-05T21:12:31.870 回答
0

我通过使用 0xFF 和 python 代码解决了这个问题。这可以防止变量增加到超过 8 位。

于 2016-09-07T12:30:52.683 回答
0

您的代码C似乎没有按预期工作,因为它显示的值比pac. 对此进行更正应该会导致显示 5 个值而不是 6 个值。为了将逻辑从Cover 复制到Python,编写了以下代码以尝试复制结果:

#! /usr/bin/env python3
def main():
    pac = bytearray(b'\x33\x55\x22\x65\x76')
    chan = 0x64
    bt_le_whiten(pac, chan)
    print('\n'.join(map('Whiten {:02}'.format, pac)))


def bt_le_whiten(data, whiten_coeff):
    for offset in range(len(data)):
        m = 1
        while m & 0xFF:
            if whiten_coeff & 0x80:
                whiten_coeff ^= 0x11
                data[offset] ^= m
            whiten_coeff <<= 1
            whiten_coeff &= 0xFF
            m <<= 1


if __name__ == '__main__':
    main()

为了模拟 8 位无符号整数,该片段& 0xFF在多个地方用于将数字截断为适当的大小。bytearray数据类型用于存储,因为在这种情况下这pac似乎是最合适的存储方法。代码仍然需要文档才能正确理解。

于 2017-01-17T22:12:14.043 回答