我正在尝试将这段代码从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位。
答案 0 :(得分:1)
在C中,您正在将数据从0写入len-1,但在Python中,您正在将数据从-1写入len-2。从这一行中删除-1:
data[len - idx -1 ] ^= m
像这样
data[len - idx] ^= m
您还需要将此行放在if:
之外whitenCoeff <<= 1
答案 1 :(得分:1)
whitenCoeff <<= 1
在一段时间后变为0,因为它是8位数据。
在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++)
答案 2 :(得分:1)
你还有一些问题。
whitenCoeff <<= 1;
位于C代码中的if
块之外,但它位于Python代码中的if
块内。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)
答案 3 :(得分:0)
我通过使用0xFF和python代码解决了这个问题。这使变量不会超过8位。
答案 4 :(得分:0)
C
中的代码似乎无法正常工作,因为它显示的值多于pac
中的值。对此进行更正应该会显示5个值而不是6个值。要将逻辑从C
复制到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
,因为在这种情况下,这似乎是最合适的存储方法。代码仍需要文档才能正确理解它。