2016-09-05 3 views
3

나는이 코드 스 니펫을 C의 파이썬으로 이식하려고하고있다. 코드가 같더라도 결과는 다르다. whitenCoeff 항상 8 비트 남아 내가 보는 문제가파이썬에 C 함수

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

:

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++; 
    } 
} 

내가 현재 파이썬에있는 것은 :

작동 코드의 C 버전입니다 C 스 니펫을 사용하지만 각 루프 패스에서 파이썬에서 8 비트보다 커집니다.

+0

필자는 파이썬 코드가 항상 더 큰 숫자 형 ('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 비트 데이터이기 때문입니다. 파이썬에서

는 그런 제한이 없다, 그래서 당신은 쓸 필요가 :

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 블록의 외부이지만, 파이썬 코드에서 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로와 AND 연산하여 파이썬 코드를 해결했다. 따라서 변수가 8 비트 이상으로 증가하지 않습니다.

0

C의 코드가 pac에서 사용할 수있는 값보다 하나 더 많은 값을 표시하므로 의도 한대로 작동하지 않습니다. 이 값을 수정하면 6 개의 값 대신 5 개의 값이 표시됩니다. Python에 걸쳐 C에서 논리를 복사하려면, 다음이 결과를 복제하기 위해 작성되었습니다 : 8 비트 부호없는 정수를 시뮬레이션하기

#! /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() 

을 니펫 & 0xFF는에 번호를 잘라내는 여러 곳에서 사용된다 적절한 크기. 이 경우에는 bytearray 데이터 유형이 pac을 저장하는 데 사용되므로 가장 적합한 저장 방법입니다. 코드를 제대로 이해하려면 문서가 필요합니다.

관련 문제