Python เขียน int แบบยาวเป็นค่าไบนารีลงในไฟล์

ฉันพยายามใช้เวลานาน int (m39 prime) และจัดเก็บเป็นไฟล์ไบนารี เมื่อฉันพยายามเขียนค่า bin ลงในไฟล์ ค่านั้นจะถูกเขียนเป็นสตริง

>>> 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

ฉันรู้สึกค่อนข้างแน่ใจว่ามีคำตอบง่ายๆ ที่น่าขัน แต่ฉันไม่ประสบความสำเร็จในการแปลง m39 เป็น bytearray หรือบัฟเฟอร์สำหรับการเขียน ฉันควรใช้ io หรือ memoryview ฯลฯ

ขอบคุณมากล่วงหน้าสำหรับความช่วยเหลือใด ๆ ที่ทุกคนสามารถให้ได้ :)

ฉันใช้ Python 2.7.3 และฉันชอบโมดูลในตัวถ้าเป็นไปได้

แก้ไข: ฉันกำลังพยายามจัดเก็บค่าเป็นไฟล์ไบนารีซึ่งจะใช้พื้นที่บนดิสก์/หน่วยความจำน้อยกว่ามาก ฉันเข้าใจว่าประเภท bin เป็นสตริงใน python แต่ฉันกำลังพยายามเขียน \x11\x11\x11\x11 not \x31\x31\x31\x31 จุดประสงค์ของฉันคือไม่พิมพ์การแสดงสตริงของค่า แต่เพื่อจัดเก็บอย่างมีประสิทธิภาพเพื่อใช้/จัดการในภายหลัง


person MadSc13ntist    schedule 24.03.2013    source แหล่งที่มา


คำตอบ (2)


คุณควรใช้โมดูล struct หรือ array ขึ้นอยู่กับโครงสร้างของข้อมูล (เช่น สำหรับอาร์เรย์ของค่าที่เป็นเนื้อเดียวกัน อาร์เรย์จะง่ายกว่า/เร็วกว่า)

person lqc    schedule 24.03.2013

โมดูล Python pickle ค่อนข้างมีประสิทธิภาพ การเป็นตัวแทนนั้นยาวกว่าค่าไบนารีดิบที่สามารถจัดเก็บได้เพียง 8 ไบต์ สิ่งนี้ใช้ได้กับ Python 2.X หรือ 3.X:

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

ผลลัพธ์การถ่ายโอนข้อมูลฐานสิบหก (1,683,373 ไบต์):

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

หากต้องการอ่านย้อนหลัง:

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

Python 3 ยังมีวิธี to_bytes และ from_bytes สำหรับจำนวนเต็มด้วย แต่ต้องใช้งานเพิ่มอีกเล็กน้อย เนื่องจากต้องคำนวณความยาวของจำนวนเต็มเป็นไบต์

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)

ผลลัพธ์การถ่ายโอนข้อมูลฐานสิบหก (1,683,365 ไบต์):

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

หากต้องการอ่านย้อนหลัง:

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

แน่นอนว่ามีรูปแบบอยู่ และจะมีประสิทธิภาพมากกว่าถ้าเก็บเลขชี้กำลังของจำนวนเฉพาะแทน

person Mark Tolonen    schedule 24.03.2013