2014-03-12 3 views
2

이 코드를 이해하는 데 도움이 필요합니다. 바이트 배열 중간에 값을 삽입하는 것을 볼 수는 있지만, Javascript에서 이것을 재 구현할 필요가 있습니다. 완전히 이해하고 싶습니다.파이썬에서 비트 조작 함수 이해하기

Array = [0] * 256 
Bit_Offset = 0 

[...] 

def AddBits(byte_offset, bit_offset, bits, value): 
    global Bit_Offset 
    global Array 

    for i in range(bits): 
     if(value & 0x01): 
      Array[(byte_offset + ((bit_offset + Bit_Offset + i)/ 8))] |= (0x01 << ((bit_offset + Bit_Offset + i) % 8)); 
     value /=2 
    Bit_Offset += bits 

그리고 그것은 다음과 같이 사용되는 :

AddBits(3, 0, 8, 0xaa) 
AddBits(3, 0, 3, 0xbb) 

편집 : 좋아, 그것은 바이트의 사용자 지정 오프셋 (offset)에 삽입 값을 수행하지만, 모든에 (나에게 매우 가난한 알고리즘과 같은주기를 찾습니다 삽입 할 비트, 정말로?). 그것을 할 수있는 더 좋은 방법이 있어야합니다!

저는 바이너리 수학에별로 좋지 않지만, 8 - bit_offset과 같은 값을 이동시키는 아이디어가 떠 올랐습니다 (첫 번째 비트가 올바른 바이트 오프셋에 있도록). 그런 다음 부분으로 분할합니다. 그것이 여러 바이트에 걸쳐 있고 마지막으로 배열의 바이트와 OR되는 경우. 이 올바른지? 어떻게 분할 부분을 구현할 수 있습니까?

+1

처럼 한 번에 한 바이트를 할 수있는 ... 내가 느끼는

한 개선에 for 루프를 변경하는 것 이런 이유로 누군가가 docstrings을 만드는 아이디어를 생각해 냈습니다 ... – mgilson

+0

당신의 이해가 정확합니다 - 임의의 비트 길이 값을 임의의 바이트와 비트 오프셋의 바이트 배열에 삽입하고 있습니다 ... . –

+0

@mgilson LMAO, 나는 확실히 동의합니다! 불행하게도이 코드는 우리가 통제 할 수 없기 때문에 문서의 부족에 대해서는 아무 것도 할 수 없으며 단지 최선을 이해하려고 노력합니다. – EliaCereda

답변

1

비트 유형 연산자를 살펴 보겠습니다.

if(value & 0x01): 

이것은 우리가 아무것도하지 않는 제로의 경우 최하위 비트가 1 또는 0입니다 있는지 확인합니다.

Array[(byte_offset + ((bit_offset + Bit_Offset + i)/ 8))] 

배열의 모든 값은 단일 바이트이기 때문에, byte_offset은 우리가 OR 비트로 갈 인덱스입니다. byte_offset에 추가 된 것은 지역 비트 카운터와 전역 비트 카운터의 비트 오프셋을 8로 나누어 바이트로 변환 한 것입니다. 마지막으로이 비트를 넣을 바이트의 인덱스를 얻습니다.

이것은 OR 연산을 수행 할 비트 위치를 계산합니다.

|= (0x01 << 

이 우리의 비트 위치를 받아 이미 무엇이든 함께 다음 관찰 보고서를 그 위치에 1을 이동합니다. if 문은 0을 필터링하기 때문에 여기서 1을 사용할 수 있습니다.

value /=2 

다음 비트를 LSB에 넣으면 오른쪽으로 약간 이동합니다. 우리는 우리가 전역 옵셋에 추가 비트를 추가 끝에

Bit_Offset += bits 

(value >>=1로 대체 될 수 있습니다).

는이 함수 오프셋 글로벌 비트에 의해 정의 된 비트 위치에서의 값의 어레이 (바이트 배열)와 비트의 현명한 논리합을 취

는 인수 비트 오프셋 않으며 인자 바이트 오프셋 무엇 . 한 번에 한 비트 씩 처리하는 이유는 배열의 인덱스를 두 개 이상 설정해야하기 때문입니다 (AddBits(3, 4, 8, 0xaa)을 시도하고 의미를 확인하십시오).

for i in range(bits): 
    Array[(byte_offset + ((bit_offset + Bit_Offset + i)/ 8))] |= ((value & 1) << ((bit_offset + Bit_Offset + i) % 8)); 
    value >>=1 

편집 : 당신은이

def AddBits2(byte_offset, bit_offset, bits, value): 
    global Bit_Offset 
    global Array 

    # precompute offsets 
    bit_offset += Bit_Offset 
    byte_offset += bit_offset/8 
    Bit_Offset += bits 

    # Mask out any extra bits in value and adjust value to align to byte 
    value = (((1 << bits) - 1) & value) << (bit_offset % 8) 

    # go through bytes and OR them in one byte at a time 
    for i in range((bits + 7)/8) : 
     Array[byte_offset + i] |= (value & 0xff) 
     value >>=8 
+0

개선해 주셔서 대단히 감사합니다. 그러나 작동하지 않는 것 같습니다 :'AddBits (0, 5, 10, 0x2aa)'는 예를 들어 다른 결과를줍니다! – EliaCereda

+0

@CrazyMonster 고정, 죄송합니다. if에서 값을 이동할 때 8에서 mod를 빼는 것을 잊어 버렸습니다. –

+0

굉장! 다시 한 번 감사드립니다 ... – EliaCereda