在我编写代码之前,我想提出一个建议:'位域'值不是可以分成字节的长度。我建议,无论何时您处理位串,您都可以按字节大小增长它们(例如,如果len(位域)%8!= 0:print'确保位域可以完全以字节表示!')确保在不同的编程语言,编程语言中的不同库以及不同的数据库中操作字段的方式不存在歧义。换句话说,数据库,python,我要推荐的库等都将存储或能够以字节数组的形式表示这个bitarray。如果提供的比特阵不能均匀地分成字节,将发生以下三种情况之一: 1)会出现错误(这是乐观的) 2)比特数将自动奇迹地左填充。 3)该bitarray将自动魔术右垫。
我建议使用某种类型的位串库。为此我使用了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
如果您知道应该提前多少位,则可以使用python字符串格式将字符串填充为零。例如,如果应该有30位,那么可以用'“{:030b}”替换上面示例代码中的最后一行。format(struct.unpack(“> I”,result [0])[0] )'这应该导致'000001110100111000110101100010'。 – srgerg