Python hashlib.file_digest: แฮชไฟล์ใหญ่โดยไม่อ่านทั้งก้อนเอง
น้องกายEngineering
เคยเขียนลูป read(65536) เพื่อแฮชไฟล์แล้วลืมปิดไฟล์ หรือบัฟเฟอร์เล็กไปทำให้ช้าไหมครับ
ตั้งแต่ Python 3.11 มี hashlib.file_digest ให้ส่งไฟล์เข้าไปแล้วได้ออบเจ็กต์แฮชพร้อมใช้ เหมือนให้พนักงานร้านช่วยชั่งของให้ครบ ไม่ต้องยกเองทีละถุง
from __future__ import annotations
import hashlib
import tempfile
import unittest
from pathlib import Path
class FileDigestTests(unittest.TestCase):
def test_matches_manual_update(self) -> None:
payload = b"showkhun-file-digest-demo\n" * 200
with tempfile.TemporaryDirectory() as tmp:
path = Path(tmp) / "sample.bin"
path.write_bytes(payload)
with path.open("rb") as fh:
digest = hashlib.file_digest(fh, "sha256").hexdigest()
manual = hashlib.sha256(payload).hexdigest()
self.assertEqual(digest, manual)
def test_accepts_algorithm_constructor(self) -> None:
with tempfile.TemporaryDirectory() as tmp:
path = Path(tmp) / "x.txt"
path.write_text("hello", encoding="utf-8")
with path.open("rb") as fh:
digest = hashlib.file_digest(fh, hashlib.sha256).hexdigest()
self.assertEqual(len(digest), 64)
if __name__ == "__main__":
unittest.main()
ข้อควรจำ
- ส่งไฟล์ที่เปิดโหมดไบนารี (
"rb") - อัลกอริทึมใส่เป็นชื่อ
"sha256"หรือ constructor ก็ได้ - ยังต้องเปิด/ปิดไฟล์เอง —
file_digestไม่ได้จัดการ path string ตรงๆ ในทุกเคส ดูเอกสารรุ่นที่คุณใช้
Recap
- ใช้
hashlib.file_digestแทนลูปอ่านเองเมื่อเช็กซัมไฟล์ - เปิดไฟล์แบบไบนารี
- เทียบผลกับค่าที่ vendor ประกาศก่อนติดตั้งของสำคัญ