2010-04-06 4 views
3

바이트 문자열에서 연속 된 4 바이트가 함께 값을 지정합니다. 그러나 각 바이트에서 7 비트 만 사용됩니다. 최상위 비트는 항상 0이므로 무시됩니다 (28 비트를 모두 만듭니다). 그래서 ...파이썬에서 바이트와 바이너리 데이터로 작업하기

b"\x00\x00\x02\x01" 

000 0000000 0010000 0001000 0000이 될 것입니다.

또는 가독성을 위해 10 000 0001. 이것이 4 바이트가 나타내는 값입니다. 하지만 진수를 원하는, 그래서이 수행

>>> 0b100000001 
257 

내가 나 자신을 모든 것을 해결할 수

을,하지만 난이 프로그램에 어떻게 통합 할 것인가?

답변

8

사용 bitshifting 및 추가 :

bytes = b"\x00\x00\x02\x01" 
i = 0 
for b in bytes: 
    i <<= 7 
    i += b  # Or use (b & 0x7f) if the last bit might not be zero. 
print(i) 

이 결과는 :

257 
+1

i + = (b & 0x7f) – miara

+0

@miara : 고마워, 네가 맞아. 나는 그것이 0이라고 가정하고 있었다. –

+0

실제로는 0입니다. 귀하의 수정되지 않은 대답이 옳았습니다. 내 질문을 수정하겠습니다. –

1

bitarray module를 사용하면 큰 숫자를 많이 더 빨리 그것을 할 수 있습니다 :

벤치 마크 (팩터 2.4 배의 속도 향상 !) :

[email protected] /tmp % python3 -m timeit -s "import tst" "tst.tst(10000)" 
10 loops, best of 3: 251 msec per loop 
[email protected] /tmp % python3 -m timeit -s "import tst" "tst.tst(100)" 
1000 loops, best of 3: 700 usec per loop 
[email protected] /tmp % python3 -m timeit -s "import sevenbittoint, os" "sevenbittoint.sevenbittoint(os.urandom(10000))" 
10 loops, best of 3: 73.7 msec per loop 
[email protected] /tmp % python3 -m timeit -s "import quick, os" "quick.quick(os.urandom(10000))"       
10 loops, best of 3: 179 msec per loop 
(막 바이어스에서) 691,363,210

quick.py :

def quick(bites): 
    i = 0 
    for b in bites: 
    i <<= 7 
    i += (b & 0x7f) 
    #i += b 
    return i 

sevenbittoint.py :

import bitarray 
import functools 

def inttobitarray(x): 
    a = bitarray.bitarray() 
    a.frombytes(x.to_bytes(1,'big')) 
    return a 

def concatter(accumulator,thisitem): 
    thisitem.pop(0) 
    for i in thisitem.tolist(): 
    accumulator.append(i) 
    return accumulator 

def sevenbittoint(bajts): 
    concatted = functools.reduce(concatter, map(inttobitarray, bajts), bitarray.bitarray()) 
    missingbits = 8 - len(concatted) % 8 
    for i in range(missingbits): concatted.insert(0,0) # zeropad 
    return int.from_bytes(concatted.tobytes(), byteorder='big') 

def tst(): 
    num = 32768 
    print(bin(num)) 
    print(sevenbittoint(num.to_bytes(2,'big'))) 

if __name__ == "__main__": 
    tst() 

tst.py : 그것이 있어야하므로 8 비트는 무시해야한다

import os 
import quick 
import sevenbittoint 

def tst(sz): 
    bajts = os.urandom(sz) 
    #for i in range(pow(2,16)): 
    # if i % pow(2,12) == 0: print(i) 
    # bajts = i.to_bytes(2, 'big') 
    a = quick.quick(bajts) 
    b = sevenbittoint.sevenbittoint(bajts) 
    if a != b: raise Exception((i, bin(int.from_bytes(bajts,'big')), a, b)) 
관련 문제