2016-09-05 41 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,因爲在這種情況下,這似乎是最合適的存儲方法。該代碼仍需要文檔才能正確理解它。