2016-09-05 5 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コードが異なるサイズの型(異なる結果を説明する)で動作するように、Pythonが常に大きな数値型( 'int')を使用することを合理的に確信しています。 – UnholySheep

答えて

1

C言語では0からlen-1までのデータを書きますが、Pythonでは-1からlen-2までのデータを書き込みます。削除-1このラインから:あなたも外にこの行を配置する必要があり、この

data[len - idx] ^= m 

よう

data[len - idx -1 ] ^= m 

場合:Cで

whitenCoeff <<= 1 
+0

悪質なこと: dは範囲外の配列で保護されますが、この場合は例外ではありません(良い発見ですが、それは次のものであった可能性はありません:)) –

+0

これはおそらくnp配列が負のインデックスをサポートしない理由です。 – vz0

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() 

ちょっとオフトピック:

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

は「

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

あなたがする必要があります:Cバージョンはすでに問題を抱えていることに注意してください同じ結果を与えるコードを書き直す

もう少し問題があります。

  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

は私が0xFFで論理積をとることにより、Pythonのコードを、それを解決しました。これは変数が8ビットを超えて増加するのを防ぎます。

0

Cのコードは、pacよりも1つ多くの値を表示しているため、意図したとおりに動作していません。これを訂正すると、6つの値の代わりに5つの値が表示されるはずです。 PythonにかけCからロジックをコピーし、以下の結果を再現する試みで書かれていたために:

#! /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を格納するために使用されるため、最も適切な格納方法です。コードはそれを正しく理解するためには依然として文書化が必要です。

関連する問題