코드를 작성하기 전에 다음과 같은 권장 사항을 작성하고 싶습니다. '비트 필드'값은 바이트로 나눌 수있는 길이가 아닙니다. 나는 당신이 비트 문자열을 다룰 때 언제든지 그것을 제안한다. len (bitfield) % 8! = 0 : print '비트 필드가 바이트로 완전히 표현 될 수 있는지 확인하라!') 다른 프로그래밍 언어, 프로그래밍 언어 내의 다른 라이브러리 및 다른 데이터베이스에서 필드가 조작되는 방법에 모호성이 없도록하십시오. 즉, 데이터베이스, 파이썬, 내가 추천하려고하는 라이브러리 등은 모두이 비트 배열을 저장하거나 바이트 배열 형태로 표현할 수 있습니다. 제공된 비트 배열이 균등하게 바이트로 나누지 않으면 다음 세 가지 중 하나가 발생합니다. 1) 오류가 발생합니다 (낙천적입니다). 2) 비트 배열이 자동으로 왼쪽으로 패딩됩니다. 3) 비트 배열은 자동으로 마술 적으로 오른쪽 패딩됩니다.
일종의 bitstring 라이브러리를 사용하는 것이 좋습니다. 이 목적으로 python-bitstring을 사용했습니다. 여기 ODBC를 처리 할 시간을 갖지 못했지만, 아이디어는 기본적으로 동일하고, srgerg의 대답 활용 :
예 :
이
#!/usr/bin/python
import pymssql
from binascii import hexlify
from bitstring import BitArray
dbconninfo = {'host': 'hostname', 'user': 'username', 'password': 'secret', 'database': 'bitexample', 'as_dict': True}
conn = pymssql.connect(**dbconninfo)
cursor = conn.cursor()
bitfield = "000001110100111000110101100010"
ba = BitArray(bin=bitfield)
print '%32d (bitfield -> BitArray -> int)' % ba.int
cursor.execute("CREATE TABLE bin_test (bin_col varbinary(max))")
cursor.execute("INSERT INTO bin_test values (%s)", (ba.int,))
cursor.execute("SELECT bin_col FROM bin_test")
results = cursor.fetchone()['bin_col'] # results now contains binary packed data '\x01\xd3\x8db'
conn.rollback()
results_int = int(hexlify(results),16)
print '%32d (bitfield -> BitArray -> int -> DB (where data is binary packed) -> unpacked with hexlify -> int)' % results_int
print '%32s (Original bitfield)' % bitfield
from_db_using_ba_hexlify_and_int_with_length = BitArray(int=int(hexlify(results),16), length=30).bin
print '%32s (From DB, decoded with hexlify, using int to instantiate BitArray, specifying length of int as 30 bits, out as bin)' %
from_db_using_ba_hexlify_and_int_with_length
from_db_using_ba_hex = BitArray(hex=hexlify(results)).bin # Can't specify length with hex
print '%32s (From DB, decoded with hexlify, using hex to instantiate BitArray, can not specify length, out as bin)' % from_db_using_ba_hex
from_db_using_ba_bytes_no_length = BitArray(bytes=results).bin # Can specify length with bytes... that's next.
print '%32s (From DB, using bytes to instantiate BitArray, no length specified, out as bin)' % from_db_using_ba_bytes_no_length
from_db_using_ba_bytes = BitArray(bytes=results,length=30).bin
print '%32s (From DB, using bytes to instantiate BitArray, specifying length of bytes as 30 bits, out as bin)' % from_db_using_ba_bytes
from_db_using_hexlify_bin = bin(int(hexlify(results),16))
print '%32s (from DB, decoded with hexlify -> int -> bin)' % from_db_using_hexlify_bin
from_db_using_hexlify_bin_ba = BitArray(bin=bin(int(hexlify(results),16))).bin
print '%32s (from DB, decoded with hexlify -> int -> bin -> BitArray instantiated with bin)' % from_db_using_hexlify_bin
from_db_using_bin = bin(int(results,16))
print '%32s (from DB, no decoding done, using bin)' % from_db_using_bin
이의 출력은 다음과 같습니다
30641506 (bitfield -> BitArray -> int)
30641506 (bitfield -> BitArray -> int -> DB (where data is binary packed) -> unpacked with hexlify -> int)
000001110100111000110101100010 (Original bitfield)
000001110100111000110101100010 (From DB, decoded with hexlify, using int to instantiate BitArray, specifying length of int as 30 bits, out as bin)
00000001110100111000110101100010 (From DB, decoded with hexlify, using hex to instantiate BitArray, can not specify length, out as bin)
00000001110100111000110101100010 (From DB, using bytes to instantiate BitArray, no length specified, out as bin)
000000011101001110001101011000 (From DB, using bytes to instantiate BitArray, specifying length of bytes as 30 bits, out as bin)
0b1110100111000110101100010 (from DB, decoded with hexlify -> int -> bin)
0b1110100111000110101100010 (from DB, decoded with hexlify -> int -> bin -> BitArray instantiated with bin)
Traceback (most recent call last):
File "./bitexample.py", line 38, in <module>
from_db_using_bin = bin(int(results,16))
ValueError: invalid literal for int() with base 16: '\x01\xd3\x8db'
을
바이트로 직접 분해 할 수있는 비트 문자열이 없으므로 (정확히 30 비트를 나타내는 문자열) 정확한 문자열을 얻는 유일한 방법은 길이를 지정하는 것이었고 심지어 결과는 일관성이 없었습니다. BitArray가 인스턴스화 된 방법에 대한 결말.
선두 0을 유지할 방법이 있습니까? 그것은 비트 필드이기 때문에 중요합니다. – Slruh
미리 알고 있어야한다면 파이썬 문자열 형식을 사용하여 문자열을 0으로 채울 수 있습니다. 예를 들어, 30 비트가 있어야한다면 위의 샘플 코드에서 마지막 줄을''{: 030b} '로 바꿀 수있다. format (struct.unpack ("> I", result [0]) [0]) '로 표시되며 결과는'000001110100111000110101100010 '입니다. – srgerg