如何存储和 write/load to/from 文件任意位数?
How to store and write/load to/from file an arbitrary number of bits?
我想编写一个哈希函数,返回 3 个整数 a、b、c 的哈希值。我希望能够选择编码每个整数的位数并将它们连接起来。例如:
a=60 (8 bits) -> 00111100
b=113 (8 bits) -> 01110001
c=5 (4 bits) -> 0101
应该给
00111100011100010101
即20 位。
给定 a、b 和 c 作为整数(60、113 和 5)以及每个整数允许的位数(8、8 和 4),我如何获取哈希并将其存储在 python 对象的总大小(20 位),并且 write/load 它到一个文件?
这里有一个 class 可以将任意数量的位写入类似文件的对象。完成后调用 flush
。
class bitwriter():
def __init__(self, f):
self.f = f
self.bits = 0
self.count = 0
def write(self, value, bitcount):
mask = (1 << bitcount) - 1
self.bits = (self.bits << bitcount) | (value & mask)
self.count += bitcount
while self.count >= 8:
byte = self.bits >> (self.count - 8)
self.f.write(byte, 1)
self.count -= 8
self.bits &= (1 << self.count ) - 1
def flush(self):
if self.count != 0:
byte = self.bits << (8 - count)
self.f.write(byte, 1)
self.bits = self.count = 0
self.f.flush()
我认为这符合您的要求。它使用我的另一个答案中引用的 bitio
模块来 write/read 位 to/from 文件。
操作系统通常要求文件大小为 8 位的倍数,因此这最终会创建一个 24 位(3 字节)的文件来存储单个 20 位值。每 20 位值 16.7% 的开销就不会发生,当然,如果你写了几个,一个接一个地写,并且直到最后一个之后才调用 flush()
。
import bitio # see
# hash function configuration
BW = 8, 8, 4 # bit widths of each integer
HW = sum(BW) # total bit width of hash
def myhash(a, b, c):
return (((((a & (2**BW[0]-1)) << BW[1]) |
b & (2**BW[1]-1)) << BW[2]) |
c & (2**BW[2]-1))
hashed = myhash(60, 113, 5)
print('{:0{}b}'.format(hashed, HW)) # --> 00111100011100010101
with open('test.bits', 'wb') as outf:
bw = bitio.BitWriter(outf)
bw.writebits(hashed, HW)
bw.flush()
with open('test.bits', 'rb') as inf:
br = bitio.BitReader(inf)
val = br.readbits(HW)
print('{:0{}b}'.format(val, HW)) # --> 00111100011100010101
我想编写一个哈希函数,返回 3 个整数 a、b、c 的哈希值。我希望能够选择编码每个整数的位数并将它们连接起来。例如:
a=60 (8 bits) -> 00111100
b=113 (8 bits) -> 01110001
c=5 (4 bits) -> 0101
应该给
00111100011100010101
即20 位。
给定 a、b 和 c 作为整数(60、113 和 5)以及每个整数允许的位数(8、8 和 4),我如何获取哈希并将其存储在 python 对象的总大小(20 位),并且 write/load 它到一个文件?
这里有一个 class 可以将任意数量的位写入类似文件的对象。完成后调用 flush
。
class bitwriter():
def __init__(self, f):
self.f = f
self.bits = 0
self.count = 0
def write(self, value, bitcount):
mask = (1 << bitcount) - 1
self.bits = (self.bits << bitcount) | (value & mask)
self.count += bitcount
while self.count >= 8:
byte = self.bits >> (self.count - 8)
self.f.write(byte, 1)
self.count -= 8
self.bits &= (1 << self.count ) - 1
def flush(self):
if self.count != 0:
byte = self.bits << (8 - count)
self.f.write(byte, 1)
self.bits = self.count = 0
self.f.flush()
我认为这符合您的要求。它使用我的另一个答案中引用的 bitio
模块来 write/read 位 to/from 文件。
操作系统通常要求文件大小为 8 位的倍数,因此这最终会创建一个 24 位(3 字节)的文件来存储单个 20 位值。每 20 位值 16.7% 的开销就不会发生,当然,如果你写了几个,一个接一个地写,并且直到最后一个之后才调用 flush()
。
import bitio # see
# hash function configuration
BW = 8, 8, 4 # bit widths of each integer
HW = sum(BW) # total bit width of hash
def myhash(a, b, c):
return (((((a & (2**BW[0]-1)) << BW[1]) |
b & (2**BW[1]-1)) << BW[2]) |
c & (2**BW[2]-1))
hashed = myhash(60, 113, 5)
print('{:0{}b}'.format(hashed, HW)) # --> 00111100011100010101
with open('test.bits', 'wb') as outf:
bw = bitio.BitWriter(outf)
bw.writebits(hashed, HW)
bw.flush()
with open('test.bits', 'rb') as inf:
br = bitio.BitReader(inf)
val = br.readbits(HW)
print('{:0{}b}'.format(val, HW)) # --> 00111100011100010101