0

I have a binary np array below:

arr = [0. 0. 1. ... 0. 1. 1.]

I would like to write it into a bin file (the output file name is 'test.bin'). I tried to use the command like this:

arr.astype('int8').tofile('test.bin')

But I found that each value in arr is converted to 8 bits.I do not want to use 8 bits to represent one number because I need to do the NIST sp800-22 randomness test, the input file must be a bin file. Could you give me some suggestions, so that I can use one bit in the bin file to represent one number in arr?

Thanks

Ehsan
  • 12,072
  • 2
  • 20
  • 33
zhonghao
  • 79
  • 5
  • There isn't a numpy dtype that only uses one bit per element. With modern computers and memory, bit twiddling isn't that useful. Nearly everything is shoved around in 8 byte (64 bit) blocks. – hpaulj Jul 10 '20 at 06:06
  • Does this answer your question? https://stackoverflow.com/questions/17536411/write-individual-bits-to-a-file-in-python – Ehsan Jul 10 '20 at 07:59

2 Answers2

0

It converts to int8 because you requested that with .astype('int8'). So leave that out and it should work as expected.

koalo
  • 2,113
  • 20
  • 31
  • I tried to remove .astype('int8') and use arr.tofile('test.bin'), it did not work. Each element consists 64 binary values. I thought it was due to the type of np array element is float64 – zhonghao Jul 10 '20 at 05:41
0

smallest memory blocks are bytes. So in general, you should not even do that. However, if you insist, here is a trick to do it:

import struct
with open("test.bnr", "wb") as f:
    for i in range(0,len(arr),8):
        bin_array = struct.pack('Q', int(''.join(arr[i:i+8].astype(str)), base=2))
        f.write(bin_array)

Convert your list to strings of length 8 bytes and then convert the strings to single unsigned doubles and write them to file. This will save it to closest multiples of 8 bytes. Of course, you can do it with other datatypes (single bytes, ints = 4bytes, ...) for closest multiples you want.

Ehsan
  • 12,072
  • 2
  • 20
  • 33