Python menulis int panjang sebagai nilai biner ke file

Saya telah mencoba mengambil int panjang (m39 prime) dan menyimpannya sebagai file biner. Ketika saya mencoba menulis nilai bin ke file, itu ditulis sebagai string.

>>> m39 = bin(2**13466917-1)
>>> open('m39', 'wb').write(m39) 
madsc13ntist@jaberwock:~/Desktop$ xxd m39 | head
0000000: 3062 3131 3131 3131 3131 3131 3131 3131  0b11111111111111
0000010: 3131 3131 3131 3131 3131 3131 3131 3131  1111111111111111
0000020: 3131 3131 3131 3131 3131 3131 3131 3131  1111111111111111
0000030: 3131 3131 3131 3131 3131 3131 3131 3131  1111111111111111
0000040: 3131 3131 3131 3131 3131 3131 3131 3131  1111111111111111
0000050: 3131 3131 3131 3131 3131 3131 3131 3131  1111111111111111
0000060: 3131 3131 3131 3131 3131 3131 3131 3131  1111111111111111
0000070: 3131 3131 3131 3131 3131 3131 3131 3131  1111111111111111
0000080: 3131 3131 3131 3131 3131 3131 3131 3131  1111111111111111

Saya merasa cukup yakin bahwa ada jawaban yang sangat sederhana untuk ini, tetapi saya belum berhasil mengubah m39 menjadi bytearray atau buffer untuk menulis. Haruskah saya menggunakan io atau memoryview, dll.

Terima kasih banyak sebelumnya atas bantuan apa pun yang dapat diberikan oleh siapa pun. :)

Saya menggunakan Python 2.7.3 dan saya lebih suka menggunakan modul bawaan jika memungkinkan.

EDIT: Saya mencoba menyimpan nilai sebagai file biner yang akan menempati lebih sedikit ruang pada disk/memori. Saya memahami bahwa tipe bin adalah string dengan python tetapi saya mencoba menulis \x11\x11\x11\x11 not \x31\x31\x31\x31. Maksud saya bukan untuk mencetak representasi string dari nilai, tetapi untuk menyimpannya secara efisien untuk digunakan/manipulasi nanti.


person MadSc13ntist    schedule 24.03.2013    source sumber


Jawaban (2)


Anda sebaiknya menggunakan modul struct atau array bergantung pada struktur data (yaitu untuk array dengan nilai homogen, array akan lebih sederhana/lebih cepat).

person lqc    schedule 24.03.2013

Modul Python pickle cukup efisien. Representasinya hanya 8 byte lebih panjang dari nilai biner mentah yang dapat disimpan. Ini berfungsi di Python 2.X atau 3.X:

import pickle
m39 = 2**13466917-1
with open('m39.dat','wb') as f:
    pickle.dump(m39,f,pickle.HIGHEST_PROTOCOL)

Hex dump yang dihasilkan (1.683.373 byte):

 80 03 8B A5 AF 19 00 FF FF FF ... FF FF FF 1F 2E

Untuk membaca kembali:

import pickle
with open('m39.dat','rb') as f:
   m39 = pickle.load(f)

Python 3 juga memiliki metode to_bytes dan from_bytes pada bilangan bulat, tetapi memerlukan lebih banyak pekerjaan karena panjang bilangan bulat dalam byte harus dihitung.

import math
m39 = 2**13466917-1
s = m39.to_bytes(math.ceil(m39.bit_length()/8),'little')
with open('m39.dat','wb') as f:
    f.write(s)

Hex dump yang dihasilkan (1.683.365 byte):

 FF FF FF FF FF FF FF FF FF FF ... FF FF FF FF 1F

Untuk membaca kembali:

with open('m39.dat','rb') as f:
    data = f.read()
m39 = int.from_bytes(data,'little')

Jelas ada pola di sana dan akan lebih efisien jika hanya menyimpan eksponen bilangan prima saja.

person Mark Tolonen    schedule 24.03.2013