2016-09-05 54 views
3

我想将这段代码从C端口移植到python。即使它是相同的代码,输出也是不同的。Python的C函数(不同的结果)

这是工作的代码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始终保持8位在C代码片段,但是在每次循环传递中,它都会在Python中超过8位。

+0

我相当肯定Python总是使用更大的数字类型(至少是'int'),所以你的Python代码使用不同的大小类型(这可以解释不同的结果) – UnholySheep

回答

1

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

data[len - idx -1 ] ^= m 

这样

data[len - idx] ^= m 

你也需要把这个线外,如果:

whitenCoeff <<= 1 
+0

恶毒的事情:你会相信你' d受到数组越界的保护,但在这种情况下不会发生(好的发现,尽管它不是下一个问题:)) –

+0

这可能是np数组不支持负指数的原因 – vz0

1

用C 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++) 
1

你”还有几个问题。

  1. whitenCoeff <<= 1;是在你的C代码if块外,但它在你的Python代码if块内。
  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) 
+0

idx被初始化len,增加-1。 idx需要10,9,8,(len-idx)需要0,1,2,... – vz0

0

我解决它由安定的Python代码为0xFF。这可以使变量不超过8位。

0

您在C中的代码似乎无法按预期工作,因为它显示的值比pac中的可用值多一个。对此进行更正应该会显示5个值而不是6个值。从CPython复制的逻辑,下面写着,企图复制的结果:

#! /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,因为在这种情况下,这似乎是最合适的存储方法。该代码仍需要文档才能正确理解它。