Python SHA-256 ด้วย hashlib
ใช้ เครื่องสร้าง Hash SHA-256 ฟรีโดยตรงในเบราว์เซอร์ของคุณ — ไม่ต้องติดตั้ง
ลอง เครื่องสร้าง Hash SHA-256 ออนไลน์ →ทุก deployment pipeline ที่ผมสร้างมาต้องการการตรวจสอบ checksum ของไฟล์ การเซ็น webhook payload หรือการสร้าง fingerprint สำหรับ cache key ในที่สุด การแฮช SHA-256 ด้วย Python ผ่าน module hashlib ที่มีอยู่แล้วในตัวนั้นรองรับทุกกรณีเหล่านั้น — และคุณมีมันติดตั้งอยู่แล้ว hashlib.sha256() ครอบ implementation ของ OpenSSL บน CPython ทำให้เร็วและรองรับ FIPS ได้ทันที สำหรับการแฮชครั้งเดียวโดยไม่ต้องเขียนโค้ด เครื่องมือ SHA-256 hash generator ออนไลน์ ให้ผลลัพธ์ได้ทันที ตัวอย่างทั้งหมดใช้ Python 3.9+
- ✓hashlib.sha256(data).hexdigest() คือวิธีมาตรฐานในการแฮช bytes — เป็นส่วนของ stdlib และรองรับโดย OpenSSL
- ✓ต้องแปลง string เป็น bytes ก่อน: hashlib.sha256("text".encode("utf-8"))
- ✓สำหรับ checksum ของไฟล์ ให้ส่งข้อมูลเป็นชิ้นๆ ด้วย .update() — อย่าอ่านไฟล์ขนาดใหญ่ทั้งหมดเข้าหน่วยความจำพร้อมกัน
- ✓HMAC-SHA256 ต้องใช้ hmac module: hmac.new(key, msg, hashlib.sha256) — SHA-256 ลำพังไม่มีคีย์
SHA-256 Hashing คืออะไร?
SHA-256 (Secure Hash Algorithm, 256-bit) รับ input ที่มีความยาวใดก็ได้และสร้าง digest ขนาดคงที่ 256 บิต (32 bytes) Input เดียวกันจะให้ output เดียวกันเสมอ แต่แม้แต่การเปลี่ยนแปลง เพียงหนึ่งบิตใน input ก็ทำให้ hash เปลี่ยนไปอย่างสิ้นเชิง — คุณสมบัตินี้เรียกว่า avalanche effect SHA-256 เป็นส่วนหนึ่งของตระกูล SHA-2 ที่ได้รับการมาตรฐานโดย NIST และเป็น รากฐานของ TLS certificate fingerprint, Git commit ID, Bitcoin block header และการตรวจสอบความสมบูรณ์ของไฟล์ อัลกอริทึมใช้โครงสร้าง Merkle-Damgård พร้อม 64 compression round เพื่อสร้าง output 256 บิต
deployment-v4.2.1
a1f7c3d8e9b2...27ae41e4649b (64 hex chars)
hex digest ข้างต้นคือรูปแบบมาตรฐาน — อักขระ hexadecimal 64 ตัว มีความยาวเท่ากันเสมอ ไม่ว่าจะแฮช 1 byte หรือ disk image ทั้งแผ่น
hashlib.sha256() — วิธีแฮชด้วย Standard Library
Module hashlib มาพร้อมกับทุก Python installation — ไม่ต้องรัน pip install เรียก hashlib.sha256() พร้อม argument เป็น bytes เพื่อสร้าง hash object แล้วดึงผลลัพธ์ด้วย .hexdigest() (hex string) หรือ .digest() (bytes ดิบ) ชื่อฟังก์ชันเขียนพิมพ์เล็ก: sha256, ไม่ใช่ SHA256
import hashlib # แฮช byte string โดยตรง digest = hashlib.sha256(b"deployment-v4.2.1").hexdigest() print(digest) # a8f5f167f44f4964e6c998dee827110c3f1de4d0280c68cba98cf70b4b5157db
ข้อผิดพลาดที่พบบ่อยที่สุดกับ hashlib.sha256() คือการส่ง str แทน bytes Python string เป็น Unicode และฟังก์ชัน hash ทำงานกับ bytes ดิบ คุณต้องเรียก .encode("utf-8") ก่อนการแฮช ข้อผิดพลาดนี้เกิดขึ้นกับเกือบทุกคนในครั้งแรก
import hashlib
# ต้องแปลง string เป็น bytes ก่อนแฮช
config_key = "redis://cache.internal:6379/0"
digest = hashlib.sha256(config_key.encode("utf-8")).hexdigest()
print(digest)
# 7d3f8c2a1b9e4f5d6c8a7b3e2f1d9c4a5b8e7f6d3c2a1b9e4f5d6c8a7b3e2f1dเมธอด .update() ช่วยให้ส่งข้อมูลแบบทีละส่วนได้ การเรียก h.update(a); h.update(b) เทียบเท่ากับ hashlib.sha256(a + b) นี่คือวิธีการแฮชไฟล์เป็นชิ้นๆ โดยไม่โหลดเนื้อหาทั้งหมดเข้าหน่วยความจำ
import hashlib h = hashlib.sha256() h.update(b"request_id=req_7f3a91bc") h.update(b"×tamp=1741614120") h.update(b"&amount=4999") print(h.hexdigest()) # Equivalent to hashlib.sha256(b"request_id=req_7f3a91bc×tamp=1741614120&amount=4999").hexdigest()
.digest() คืนค่า 32 bytes ดิบ .hexdigest() คืนค่า hex string 64 ตัวอักษร ใช้ .digest() เมื่อต้องส่งผลลัพธ์เข้า HMAC, การเข้ารหัส Base64 หรือ binary protocol ใช้ .hexdigest() สำหรับ logging, คอลัมน์ในฐานข้อมูล และการเปรียบเทียบ checksumHMAC-SHA256 — Keyed Hashing ด้วย hmac Module
SHA-256 ลำพังไม่มีแนวคิดเรื่องคีย์ลับ — ใครก็ตามที่มี input เดียวกันสามารถคำนวณ hash เดียวกันได้ หากต้องการพิสูจน์ว่าข้อความมาจากผู้ส่งที่เฉพาะเจาะจง (webhook verification, API request signing, token authentication) คุณต้องการ HMAC Module hmac เป็นส่วนหนึ่งของ standard library ของ Python และรวมคีย์เข้าสู่กระบวนการแฮช เพื่อให้เฉพาะผู้ที่มีคีย์เท่านั้นที่สามารถสร้างหรือตรวจสอบ digest เดียวกันได้
import hmac
import hashlib
# ตรวจสอบ webhook signature
secret_key = b"whsec_9f3a7b2e1d4c8a5b"
payload = b'{"event":"invoice.paid","invoice_id":"inv_8d2c","amount":14900}'
signature = hmac.new(secret_key, payload, hashlib.sha256).hexdigest()
print(signature)
# 64-character hex HMAC-SHA256 digestการตรวจสอบ HMAC ที่รับเข้ามาต้องใช้ hmac.compare_digest() แทนตัวดำเนินการ == ตัวดำเนินการความเท่ากันมีความเสี่ยงต่อ timing attack — มันหยุดทำงานเมื่อพบ byte ที่ไม่ตรงกันตัวแรก และผู้โจมตีสามารถวัดเวลาตอบสนองเพื่อเดา signature ที่ถูกต้องทีละ byte compare_digest() ทำงานในเวลาคงที่โดยไม่คำนึงว่าความไม่ตรงกันเกิดขึ้นที่ไหน
import hmac
import hashlib
def verify_webhook(payload: bytes, received_sig: str, secret: bytes) -> bool:
"""ตรวจสอบ webhook signature โดยใช้การเปรียบเทียบแบบ constant-time"""
expected = hmac.new(secret, payload, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, received_sig)
# จำลองการตรวจสอบ webhook แบบ Stripe
incoming_payload = b'{"event":"payment.completed","amount":4999}'
incoming_signature = "a1b2c3d4e5f6..." # จาก X-Signature header
webhook_secret = b"whsec_9f3a7b2e1d4c"
if verify_webhook(incoming_payload, incoming_signature, webhook_secret):
print("Signature ถูกต้อง — ดำเนินการต่อ")
else:
print("Signature ไม่ตรงกัน — ปฏิเสธคำขอ")HMAC-SHA256 Request Signing
การเซ็น API request ใช้หลักการเดียวกัน: สร้าง canonical string จากส่วนประกอบของ request (method, path, timestamp, body hash) แล้วเซ็นด้วยคีย์ลับของคุณ AWS Signature V4, Stripe และ GitHub webhook ล้วนใช้รูปแบบนี้ในรูปแบบต่างๆ
import hmac
import hashlib
import time
def sign_request(method: str, path: str, body: bytes, secret: bytes) -> str:
"""สร้าง HMAC-SHA256 signature สำหรับ API request"""
timestamp = str(int(time.time()))
body_hash = hashlib.sha256(body).hexdigest()
# Canonical string: method + path + timestamp + body hash
canonical = f"{method}\n{path}\n{timestamp}\n{body_hash}"
signature = hmac.new(secret, canonical.encode("utf-8"), hashlib.sha256).hexdigest()
return f"ts={timestamp},sig={signature}"
# ตัวอย่างการใช้งาน
api_secret = b"sk_live_9f3a7b2e1d4c8a5b6e7f"
request_body = b'{"customer_id":"cust_4f2a","plan":"enterprise"}'
auth_header = sign_request("POST", "/api/v2/subscriptions", request_body, api_secret)
print(f"Authorization: HMAC-SHA256 {auth_header}")
# Authorization: HMAC-SHA256 ts=1741614120,sig=7d3f8c2a...Base64-Encoded HMAC-SHA256
บาง API (AWS Signature V4, payment gateway บางตัว) คาดหวัง HMAC result เป็น Base64-encoded string แทน hex ความแตกต่างคือ: hex ใช้ 64 ตัวอักษร ส่วน Base64 ใช้ 44 ตัวอักษรสำหรับ digest 32 bytes เดียวกัน
import hmac
import hashlib
import base64
secret = b"webhook_secret_9f3a"
message = b"POST /api/v2/events 1741614120"
# Hex output: 64 ตัวอักษร
hex_sig = hmac.new(secret, message, hashlib.sha256).hexdigest()
print(f"Hex: {hex_sig}")
# Base64 output: 44 ตัวอักษร (สั้นกว่า พบบ่อยใน HTTP header)
raw_sig = hmac.new(secret, message, hashlib.sha256).digest()
b64_sig = base64.b64encode(raw_sig).decode("ascii")
print(f"Base64: {b64_sig}")การแฮช datetime, UUID และ Custom Object
SHA-256 ทำงานกับ bytes ดิบ ดังนั้น type ที่ไม่ใช่ bytes — datetime, UUID, dataclass, Pydantic model — ต้องแปลงเป็น bytes ก่อนแฮช ไม่มีการแปลงอัตโนมัติ คุณเลือกรูปแบบที่เป็นมาตรฐานเองได้ สำหรับการแฮชที่กำหนดแน่นอนข้ามระบบ ให้ใช้ encoding ที่ชัดเจนและรูปแบบ serialization ที่เสถียร (ISO 8601 สำหรับ datetime, รูปแบบ string มาตรฐานสำหรับ UUID, JSON ที่ sort key แล้วสำหรับ dict)
import hashlib
import uuid
from datetime import datetime, timezone
# datetime — ใช้ ISO 8601 พร้อม UTC offset ที่ชัดเจนเพื่อความสามารถในการพกพา
event_time = datetime(2026, 3, 28, 12, 0, 0, tzinfo=timezone.utc)
time_hash = hashlib.sha256(event_time.isoformat().encode("utf-8")).hexdigest()
print(f"datetime hash: {time_hash[:16]}...")
# UUID — แฮชในรูปแบบ string มาตรฐาน (พิมพ์เล็ก พร้อมยัติภังค์)
record_id = uuid.uuid4()
uuid_hash = hashlib.sha256(str(record_id).encode("utf-8")).hexdigest()
print(f"UUID hash: {uuid_hash[:16]}...")สำหรับ custom object ให้แปลงเป็น bytes ในรูปแบบที่กำหนดแน่นอนก่อนแฮช JSON ที่ sort key แล้วเหมาะสำหรับ object ที่คล้าย dict:
import hashlib
import json
from dataclasses import dataclass, asdict
@dataclass
class Event:
id: str
type: str
amount: int
timestamp: str
def hash_event(event: Event) -> str:
"""แฮช dataclass โดยใช้ JSON ที่ sort key แล้วเพื่อความแน่นอน"""
canonical = json.dumps(asdict(event), sort_keys=True, separators=(",", ":"))
return hashlib.sha256(canonical.encode("utf-8")).hexdigest()
e = Event(id="evt_4f2a", type="payment.completed", amount=4999, timestamp="2026-03-28T12:00:00Z")
print(hash_event(e)) # ผลลัพธ์เหมือนกันทุกครั้งและทุกเครื่องsort_keys=True) เมื่อแฮช object ที่ผ่าน JSON serialization ลำดับการแทรก dict ใน Python 3.7+ คงที่ แต่อาจแตกต่างกันตาม serialization path ทำให้ได้ hash ต่างกันสำหรับข้อมูลที่เหมือนกันSHA-256 File Checksum — ตรวจสอบการดาวน์โหลดและ Artifact
การคำนวณ SHA-256 checksum ของไฟล์เป็นหนึ่งในการใช้งานอัลกอริทึมนี้ที่พบบ่อยที่สุด คุณจะเห็นมันทุกที่: หน้า release สำหรับ Go binary, Python wheel file, Docker image manifest, firmware update จุดสำคัญคือต้องอ่านไฟล์เป็นชิ้นๆ แทนที่จะโหลดทั้งหมดพร้อมกัน — ISO image ขนาด 2 GB ไม่ควรต้องใช้ RAM 2 GB เพียงเพื่อแฮชมัน
import hashlib
def sha256_checksum(filepath: str, chunk_size: int = 8192) -> str:
"""คำนวณ SHA-256 hash ของไฟล์โดยอ่านเป็นชิ้นๆ เพื่อประหยัดหน่วยความจำ"""
h = hashlib.sha256()
with open(filepath, "rb") as f:
for chunk in iter(lambda: f.read(chunk_size), b""):
h.update(chunk)
return h.hexdigest()
# แฮช release artifact
checksum = sha256_checksum("/tmp/release-v4.2.1.tar.gz")
print(f"SHA-256: {checksum}")Python 3.11 เพิ่ม hashlib.file_digest() ซึ่งอ่านข้อมูลเป็นชิ้นๆ ภายในและอาจใช้ zero-copy optimization บน platform ที่รองรับ หากใช้ 3.11 หรือใหม่กว่า ควรใช้แทน loop แบบ manual
import hashlib
with open("/tmp/release-v4.2.1.tar.gz", "rb") as f:
digest = hashlib.file_digest(f, "sha256")
print(digest.hexdigest())ตรวจสอบไฟล์ที่ดาวน์โหลดกับ Checksum ที่รู้จัก
import hashlib
import hmac as hmac_mod # เฉพาะสำหรับ compare_digest
def verify_checksum(filepath: str, expected_hex: str) -> bool:
"""ตรวจสอบ SHA-256 checksum โดยใช้การเปรียบเทียบแบบ constant-time"""
h = hashlib.sha256()
with open(filepath, "rb") as f:
for chunk in iter(lambda: f.read(8192), b""):
h.update(chunk)
return hmac_mod.compare_digest(h.hexdigest(), expected_hex.lower())
# ตรวจสอบ release artifact
expected = "a8f5f167f44f4964e6c998dee827110c3f1de4d0280c68cba98cf70b4b5157db"
if verify_checksum("/tmp/release-v4.2.1.tar.gz", expected):
print("Checksum ตรงกัน — ไฟล์สมบูรณ์")
else:
print("Checksum ไม่ตรงกัน — ไฟล์อาจเสียหายหรือถูกดัดแปลง")hmac.compare_digest() สำหรับการเปรียบเทียบ checksum เสมอ แม้จะไม่มีคีย์ลับ การเปรียบเทียบแบบ constant-time ป้องกันการรั่วไหลข้อมูลผ่าน timing ตัวดำเนินการ == ทำงานได้ตามฟังก์ชัน แต่ไม่ปลอดภัยสำหรับบริบทที่เกี่ยวข้องกับความปลอดภัยSHA-256 พร้อม Base64 Encoding
บาง protocol คาดหวัง SHA-256 digest เป็น Base64 string แทน hex HTTP header อย่าง Content-Digest และ Integrity (Subresource Integrity ในเบราว์เซอร์) ใช้ Base64 และ JWT signature เป็น Base64url-encoded เคล็ดลับคือต้อง Base64-encode bytes ดิบจาก .digest() ไม่ใช่ hex string
import hashlib
import base64
data = b"integrity check payload"
# ถูกต้อง: Base64 ของ bytes ดิบ (32 bytes → 44 ตัวอักษร Base64)
raw_digest = hashlib.sha256(data).digest()
b64_digest = base64.b64encode(raw_digest).decode("ascii")
print(f"sha256-{b64_digest}")
# sha256-<44 ตัวอักษร>
# ผิด: Base64 ของ hex string (64 ASCII bytes → 88 ตัวอักษร Base64 — ขนาดเป็นสองเท่า)
hex_digest = hashlib.sha256(data).hexdigest()
wrong = base64.b64encode(hex_digest.encode()).decode()
print(f"ความยาวผิด: {len(wrong)} ตัวอักษร") # 88 — ไม่ใช่สิ่งที่ API คาดหวัง.digest() เสมอ ไม่ใช่ .hexdigest() ก่อน Base64 encodinghashlib.sha256() Reference
constructor และเมธอดบน SHA-256 hash object:
parameter ของ hmac.new() สำหรับ keyed hashing:
cryptography Library — SHA-256 API ทางเลือก
Package cryptography มี API ที่แตกต่างออกไปสำหรับ SHA-256 ผ่าน hazmat primitive ส่วนตัวแทบไม่เคยใช้มัน เมื่อต้องการแค่ hash — hashlib ง่ายกว่าและไม่มี external dependency แต่หากโปรเจกต์ของคุณใช้ cryptography อยู่แล้วสำหรับ TLS, X.509 หรือ symmetric encryption การใช้ hash API ของมันก็ทำให้ทุกอย่างอยู่ใน library เดียว และมีการจัดการ error ที่สอดคล้องกัน
from cryptography.hazmat.primitives import hashes from cryptography.hazmat.backends import default_backend digest = hashes.Hash(hashes.SHA256(), backend=default_backend()) digest.update(b"deployment-v4.2.1") result = digest.finalize() # raw 32 bytes print(result.hex()) # 64-char hex string # a8f5f167f44f4964e6c998dee827110c3f1de4d0280c68cba98cf70b4b5157db
cryptography ต้องการ pip install cryptography hash object ใช้ได้ครั้งเดียว: การเรียก .finalize() ครั้งที่สองจะเกิด AlreadyFinalized ใช้ .copy() ก่อน finalize หากต้องการแตกสาขาสถานะ hashแฮชข้อมูลจากไฟล์และ API Response
สองสถานการณ์ที่พบบ่อยคือ: การแฮชไฟล์บน disk เพื่อตรวจสอบ release artifact และการแฮช HTTP response body เพื่อใช้เป็น cache key หรือตรวจสอบ webhook
อ่านไฟล์ → คำนวณ SHA-256 → เปรียบเทียบ
import hashlib
import sys
def hash_file_safe(filepath: str) -> str | None:
"""แฮชไฟล์พร้อม error handling ที่เหมาะสม"""
try:
h = hashlib.sha256()
with open(filepath, "rb") as f:
for chunk in iter(lambda: f.read(16384), b""):
h.update(chunk)
return h.hexdigest()
except FileNotFoundError:
print(f"ข้อผิดพลาด: ไม่พบ {filepath}", file=sys.stderr)
return None
except PermissionError:
print(f"ข้อผิดพลาด: ไม่มีสิทธิ์อ่าน {filepath}", file=sys.stderr)
return None
result = hash_file_safe("/etc/nginx/nginx.conf")
if result:
print(f"SHA-256: {result}")HTTP Response → แฮช Body สำหรับ Cache Key
import hashlib
import urllib.request
import json
def fetch_and_hash(url: str) -> tuple[dict, str]:
"""ดึง JSON จาก API และคืนค่าทั้งข้อมูลและ SHA-256 hash"""
try:
with urllib.request.urlopen(url, timeout=10) as resp:
body = resp.read()
content_hash = hashlib.sha256(body).hexdigest()
data = json.loads(body)
return data, content_hash
except urllib.error.URLError as exc:
raise ConnectionError(f"ดึงข้อมูลจาก {url} ล้มเหลว: {exc}") from exc
# Cache key ตาม response content
data, digest = fetch_and_hash("https://api.exchange.internal/v2/rates")
print(f"Response hash: {digest[:16]}...")
print(f"EUR/USD: {data.get('rates', {}).get('EUR', 'N/A')}")สำหรับการตรวจสอบครั้งเดียวอย่างรวดเร็ว SHA-256 generator ของ ToolDeck ทำงานในเบราว์เซอร์ทั้งหมด — ไม่ต้องเขียนโค้ด
SHA-256 Hashing ผ่าน Command Line
บางครั้งคุณแค่ต้องการ hash อย่างรวดเร็วใน terminal ระหว่าง incident หรือ deployment Module hashlib ของ Python ไม่มี CLI subcommand ในตัว (ต่างจาก python3 -m json.tool), แต่คุณสามารถใช้ one-liner หรือ system tool ได้
# Python one-liner echo -n "deployment-v4.2.1" | python3 -c "import hashlib,sys; print(hashlib.sha256(sys.stdin.buffer.read()).hexdigest())" # macOS / BSD echo -n "deployment-v4.2.1" | shasum -a 256 # Linux (coreutils) echo -n "deployment-v4.2.1" | sha256sum # OpenSSL (ข้ามแพลตฟอร์ม) echo -n "deployment-v4.2.1" | openssl dgst -sha256
# แฮช release tarball sha256sum release-v4.2.1.tar.gz # หรือ openssl dgst -sha256 release-v4.2.1.tar.gz # ตรวจสอบกับ checksum ที่รู้จัก echo "a8f5f167f44f4964e6c998dee827110c release-v4.2.1.tar.gz" | sha256sum -c - # release-v4.2.1.tar.gz: OK
echo -n (ไม่มี newline ท้าย) เสมอเมื่อแฮช string บน command line echo ธรรมดาจะเพิ่ม \n ซึ่งเปลี่ยน hash นี่คือสาเหตุอันดับหนึ่งที่ทำให้ได้ hash ต่างกันระหว่าง Python และ shellทางเลือกประสิทธิภาพสูง — hashlib กับ OpenSSL และ pycryptodome
บน CPython hashlib.sha256() ใช้ C implementation ของ OpenSSL อยู่แล้ว จึงเร็ว — โดยทั่วไปทำได้ 500+ MB/s บน hardware สมัยใหม่
หาก SHA-256 hashing ปรากฏใน profiler ของคุณ — เช่น คุณกำลังคำนวณ checksum สำหรับไฟล์หลายพันไฟล์ ใน CI pipeline หรือแฮช request body ทุกอัน — มีสองตัวเลือก: ปรับรูปแบบการเรียก hashlib หรือเปลี่ยนไปใช้ pycryptodome สำหรับ crypto API ครบวงจรที่รองรับ SHA-3 และ BLAKE2 ด้วย:
pip install pycryptodome
from Crypto.Hash import SHA256 h = SHA256.new() h.update(b"deployment-v4.2.1") print(h.hexdigest()) # a8f5f167f44f4964e6c998dee827110c3f1de4d0280c68cba98cf70b4b5157db
สำหรับการแฮชไฟล์แบบขนานที่มี throughput สูง การปรับปรุงที่ใหญ่กว่ามาจากการลด Python overhead ผ่านการใช้ chunk ขนาดใหญ่ขึ้นและ threading:
import hashlib
import os
from pathlib import Path
from concurrent.futures import ThreadPoolExecutor
def hash_file(path: Path) -> tuple[str, str]:
"""แฮชไฟล์เดียวและคืนค่า (path, hex digest)"""
h = hashlib.sha256()
with open(path, "rb") as f:
for chunk in iter(lambda: f.read(65536), b""): # chunks ขนาด 64 KB
h.update(chunk)
return str(path), h.hexdigest()
def hash_directory(directory: str, pattern: str = "*.tar.gz") -> dict[str, str]:
"""แฮชไฟล์ที่ตรงกันทั้งหมดแบบขนานโดยใช้ thread"""
files = list(Path(directory).glob(pattern))
results = {}
with ThreadPoolExecutor(max_workers=os.cpu_count()) as pool:
for path, digest in pool.map(hash_file, files):
results[path] = digest
return results
# แฮช release artifact ทั้งหมดแบบขนาน
checksums = hash_directory("/var/releases", "*.tar.gz")
for path, digest in checksums.items():
print(f"{digest} {path}")การใช้ chunk ขนาด 64 KB แทน 8 KB ลดจำนวนการเรียก Python-to-C ลง 8 เท่า Thread ทำงานได้ดีตรงนี้เพราะ GIL ถูกปลดปล่อยระหว่าง hashing ระดับ C — คอขวดคือ disk I/O ไม่ใช่ CPU
แสดงผลใน Terminal ด้วย Syntax Highlighting
Library rich มีประโยชน์เมื่อต้องการตรวจสอบไฟล์หลายไฟล์และต้องการตารางแสดงสถานะ pass/fail ต่อไฟล์แทนที่จะเป็น hex output ที่เลื่อนผ่าน
pip install rich
import hashlib
from pathlib import Path
from rich.console import Console
from rich.table import Table
console = Console()
def hash_and_display(files: list[str], expected: dict[str, str]) -> None:
"""แฮชไฟล์และแสดงผลพร้อมสีแสดงสถานะ"""
table = Table(title="SHA-256 Verification")
table.add_column("File", style="cyan")
table.add_column("SHA-256", style="dim", max_width=20)
table.add_column("Status")
for filepath in files:
h = hashlib.sha256()
with open(filepath, "rb") as f:
for chunk in iter(lambda: f.read(8192), b""):
h.update(chunk)
digest = h.hexdigest()
name = Path(filepath).name
status = "[green]✓ OK[/green]" if expected.get(name) == digest else "[red]✗ MISMATCH[/red]"
table.add_row(name, f"{digest[:16]}...", status)
console.print(table)
# ตัวอย่างการใช้งาน
expected_checksums = {
"api-gateway-v3.1.tar.gz": "a8f5f167f44f4964...",
"worker-v3.1.tar.gz": "7d3f8c2a1b9e4f5d...",
}
hash_and_display(
["/var/releases/api-gateway-v3.1.tar.gz", "/var/releases/worker-v3.1.tar.gz"],
expected_checksums,
)console.print(data, highlight=False) หรือเปลี่ยนเส้นทาง ไปยังไฟล์ด้วย Console(file=open(...))การทำงานกับไฟล์ขนาดใหญ่
รูปแบบ .update() แบบชิ้นๆ จัดการไฟล์ขนาดใดก็ได้ด้วยการใช้หน่วยความจำคงที่ สำหรับไฟล์ขนาดใหญ่มาก (disk image หลาย GB, database backup) ความกังวลหลักเปลี่ยนจากหน่วยความจำเป็นการแสดงผลให้ผู้ใช้ — การแฮช 10 GB ที่ 500 MB/s ยังใช้เวลา 20 วินาที และความเงียบในช่วงนั้นทำให้คนกังวล
import hashlib
import os
def sha256_with_progress(filepath: str) -> str:
"""แฮชไฟล์ขนาดใหญ่พร้อมรายงานความคืบหน้าไปยัง stderr"""
file_size = os.path.getsize(filepath)
h = hashlib.sha256()
bytes_read = 0
with open(filepath, "rb") as f:
while chunk := f.read(1 << 20): # chunks ขนาด 1 MB
h.update(chunk)
bytes_read += len(chunk)
pct = (bytes_read / file_size) * 100
print(f"\r กำลังแฮช: {pct:.1f}% ({bytes_read >> 20} MB / {file_size >> 20} MB)",
end="", flush=True)
print() # ขึ้นบรรทัดใหม่หลัง progress
return h.hexdigest()
digest = sha256_with_progress("/mnt/backups/db-snapshot-2026-03.sql.gz")
print(f"SHA-256: {digest}")NDJSON / JSON Lines — แฮชแต่ละ Record แยกกัน
import hashlib
import json
def hash_ndjson_records(filepath: str) -> dict[str, str]:
"""แฮช JSON record แต่ละรายการในไฟล์ NDJSON เพื่อตรวจหาข้อมูลซ้ำ"""
seen = {}
with open(filepath, "r", encoding="utf-8") as f:
for line_num, line in enumerate(f, 1):
line = line.strip()
if not line:
continue
try:
record = json.loads(line)
# Normalize ก่อนแฮช: sort key เพื่อผลลัพธ์ที่กำหนดแน่นอน
canonical = json.dumps(record, sort_keys=True, separators=(",", ":"))
digest = hashlib.sha256(canonical.encode("utf-8")).hexdigest()
if digest in seen:
print(f"บรรทัด {line_num}: ข้อมูลซ้ำกับบรรทัด {seen[digest]}")
else:
seen[digest] = line_num
except json.JSONDecodeError:
print(f"บรรทัด {line_num}: JSON ไม่ถูกต้อง ข้ามไป")
print(f"ประมวลผล {line_num} บรรทัด, {len(seen)} record ที่ไม่ซ้ำกัน")
return seen
hash_ndjson_records("telemetry-events-2026-03.ndjson")hashlib.sha256(data) แบบ one-shot ไปเป็น loop .update() แบบชิ้นๆ เมื่อไฟล์มีขนาดเกิน 50–100 MB ต่ำกว่า threshold นั้น การอ่านไฟล์ทั้งหมดด้วย f.read() ก็ใช้ได้ — การใช้หน่วยความจำจะเท่ากับขนาดไฟล์โดยประมาณข้อผิดพลาดที่พบบ่อย
ปัญหา: hashlib.sha256('text') เกิด TypeError: Unicode-objects must be encoded before hashing ฟังก์ชันต้องการ bytes ไม่ใช่ str
วิธีแก้ไข: Encode string ก่อน: hashlib.sha256('text'.encode('utf-8')) หรือใช้ b'' literal สำหรับค่าที่กำหนดไว้ตายตัว
import hashlib
digest = hashlib.sha256("deployment-v4.2.1").hexdigest()
# TypeError: Unicode-objects must be encoded before hashingimport hashlib
digest = hashlib.sha256("deployment-v4.2.1".encode("utf-8")).hexdigest()
# ใช้งานได้ — คืนค่า hex string 64 ตัวอักษรปัญหา: ตัวดำเนินการ == หยุดทำงานเมื่อพบ byte ที่ไม่ตรงกันตัวแรก ผู้โจมตีสามารถวัดเวลาตอบสนองเพื่อเดา signature ที่ถูกต้องทีละ byte
วิธีแก้ไข: ใช้ hmac.compare_digest() สำหรับการเปรียบเทียบที่เกี่ยวข้องกับความปลอดภัยทั้งหมด — ทำงานในเวลาคงที่โดยไม่คำนึงว่าความไม่ตรงกันเกิดขึ้นที่ไหน
received_sig = request.headers["X-Signature"]
expected_sig = hmac.new(key, body, hashlib.sha256).hexdigest()
if received_sig == expected_sig: # เสี่ยงต่อ timing attack
process_webhook(body)received_sig = request.headers["X-Signature"]
expected_sig = hmac.new(key, body, hashlib.sha256).hexdigest()
if hmac.compare_digest(received_sig, expected_sig): # constant-time
process_webhook(body)ปัญหา: base64.b64encode(digest.hexdigest().encode()) สร้าง string 88 ตัวอักษร — เป็นสองเท่าของ 44 ตัวอักษรที่คาดหวัง API ที่คาดหวัง Base64-encoded SHA-256 จะปฏิเสธ
วิธีแก้ไข: เรียก .digest() (bytes ดิบ) ก่อน Base64-encoding ไม่ใช่ .hexdigest() (hex string)
import hashlib, base64 hex_str = hashlib.sha256(data).hexdigest() b64 = base64.b64encode(hex_str.encode()) # 88 ตัวอักษร — ผิด!
import hashlib, base64 raw = hashlib.sha256(data).digest() b64 = base64.b64encode(raw) # 44 ตัวอักษร — ถูกต้อง
ปัญหา: hashlib.sha256(open('large.iso', 'rb').read()) โหลดไฟล์ทั้งหมดเข้าหน่วยความจำ ไฟล์ 4 GB ต้องการ RAM 4 GB เพียงสำหรับการคำนวณ hash
วิธีแก้ไข: อ่านเป็นชิ้นๆ ด้วย loop และ .update() การใช้หน่วยความจำคงที่โดยไม่คำนึงถึงขนาดไฟล์
import hashlib
# โหลดไฟล์ 4 GB ทั้งหมดเข้าหน่วยความจำ
digest = hashlib.sha256(open("disk.iso", "rb").read()).hexdigest()import hashlib
h = hashlib.sha256()
with open("disk.iso", "rb") as f:
for chunk in iter(lambda: f.read(8192), b""):
h.update(chunk)
digest = h.hexdigest() # การใช้หน่วยความจำคงที่hashlib vs hmac vs ทางเลือกอื่น — เปรียบเทียบอย่างย่อ
สำหรับการแฮชทั่วไป — checksum, cache key, content fingerprinting — ใช้ hashlib.sha256() เปลี่ยนไปใช้ hmac.new() ทันทีที่ต้องการคีย์ลับ (webhook, API signature, token authentication) ใช้ library cryptography เฉพาะเมื่อโปรเจกต์ใช้มันอยู่แล้วสำหรับการเข้ารหัสหรือ TLS — การเพิ่ม C extension dependency เพียงเพื่อ hashing นั้นเกินความจำเป็นเมื่อ hashlib รองรับโดย OpenSSL อยู่แล้ว
SHA-256 ถอดรหัสได้หรือไม่? — Hashing กับ Encryption
คำตอบสั้น: ไม่ได้ SHA-256 เป็นฟังก์ชันทางเดียว อัลกอริทึมถูกออกแบบให้ไม่สามารถย้อนกลับได้ — คุณไม่สามารถสร้าง input ต้นฉบับขึ้นมาจาก digest 256 บิตได้ นี่ไม่ใช่ข้อจำกัดของ implementation แต่เป็นคุณสมบัติทางคณิตศาสตร์ของฟังก์ชัน hash พื้นที่ output 256 บิตมีขนาดมหาศาล (2256 ค่าที่เป็นไปได้) และฟังก์ชันทิ้งข้อมูลไประหว่าง 64 compression round
ผู้โจมตีสามารถลอง brute-force หรือ dictionary attack กับ input ที่อ่อนแอ (รหัสผ่านทั่วไป, string สั้นๆ) แต่สำหรับ input ที่มี entropy เพียงพอ — API key, random token, เนื้อหาไฟล์ — การย้อนกลับ SHA-256 นั้นไม่สามารถทำได้จริงด้วย hardware ปัจจุบัน หากต้องการการแปลงแบบกลับได้ ให้ใช้ symmetric encryption:
# Hashing — ทางเดียว ไม่สามารถกู้คืน input ต้นฉบับได้ import hashlib digest = hashlib.sha256(b"secret-config-value").hexdigest() # ไม่มีทางได้ "secret-config-value" กลับมาจาก digest # Encryption — สองทาง สามารถถอดรหัสด้วย key ได้ from cryptography.fernet import Fernet key = Fernet.generate_key() cipher = Fernet(key) encrypted = cipher.encrypt(b"secret-config-value") decrypted = cipher.decrypt(encrypted) print(decrypted) # b"secret-config-value" — กู้คืน input ต้นฉบับได้
สำหรับวิธีที่ไม่ต้องติดตั้งอะไรในการ สร้าง SHA-256 hash อย่างรวดเร็ว เครื่องมือออนไลน์ทำงานในเบราว์เซอร์ทั้งหมด
จะตรวจสอบว่า String เป็น SHA-256 Hash ที่ถูกต้องใน Python ได้อย่างไร
SHA-256 hex digest ที่ถูกต้องประกอบด้วยอักขระ hexadecimal ครบ 64 ตัว (0-9, a-f, A-F) การตรวจสอบอย่างรวดเร็วก่อนประมวลผล input ที่ไม่น่าเชื่อถือช่วยป้องกัน error ที่สับสนใน downstream
import re
def is_sha256_hex(value: str) -> bool:
"""ตรวจสอบว่า string ตรงกับรูปแบบ SHA-256 hex digest หรือไม่"""
return bool(re.fullmatch(r"[a-fA-F0-9]{64}", value))
# ตัวอย่างทดสอบ
print(is_sha256_hex("e3b0c44298fc1c149afbf4c8996fb924"
"27ae41e4649b934ca495991b7852b855")) # True — SHA-256 ของ string ว่าง
print(is_sha256_hex("e3b0c44298fc1c14")) # False — สั้นเกินไป
print(is_sha256_hex("zzzz" * 16)) # False — อักขระ hex ไม่ถูกต้องคำถามที่พบบ่อย
จะแฮช string ด้วย SHA-256 ใน Python ได้อย่างไร?
เรียก hashlib.sha256() พร้อม string ที่แปลงเป็น bytes แล้ว string ใน Python เป็น Unicode และฟังก์ชัน hash ทำงานกับ bytes ดิบ จึงต้องเรียก .encode("utf-8") ก่อน เมธอด .hexdigest() จะคืนค่า hex string 64 ตัวอักษรที่คุ้นเคย
import hashlib
api_key = "sk_live_9f3a7b2e1d4c"
digest = hashlib.sha256(api_key.encode("utf-8")).hexdigest()
print(digest)
# e3b7c4a1f8d2...64 hex charactersสามารถถอดรหัส SHA-256 กลับเป็นข้อความต้นฉบับได้หรือไม่?
ไม่ได้ SHA-256 เป็นฟังก์ชันทางเดียว — มันแปลง input ที่มีความยาวใดก็ได้ไปเป็น output 256 บิตที่มีขนาดคงที่และทิ้งโครงสร้างไปในกระบวนการ ไม่มีค่าผกผันทางคณิตศาสตร์ ผู้โจมตีสามารถลอง brute-force หรือค้นหาใน rainbow table กับ input ที่อ่อนแอ (รหัสผ่านสั้น คำทั่วไป) แต่สำหรับ input ที่มี entropy เพียงพอ การย้อนกลับ SHA-256 นั้นไม่สามารถทำได้ในทางคำนวณ หากต้องการการแปลงแบบกลับได้ ให้ใช้การเข้ารหัส (AES-GCM, Fernet) แทน
.digest() และ .hexdigest() ต่างกันอย่างไร?
.digest() คืนค่า 32 bytes ดิบของ hash เป็น bytes object ส่วน .hexdigest() คืนค่าข้อมูลเดียวกันในรูปแบบ hex string พิมพ์เล็ก 64 ตัวอักษร ใช้ .digest() เมื่อต้องการ binary output — ส่งเข้า HMAC, การเข้ารหัส Base64 หรือ binary protocol ใช้ .hexdigest() เมื่อต้องการ string ที่อ่านได้สำหรับ logging, เก็บในฐานข้อมูล หรือการเปรียบเทียบ checksum
import hashlib h = hashlib.sha256(b"deployment-v4.2.1") print(len(h.digest())) # 32 (bytes) print(len(h.hexdigest())) # 64 (hex characters)
จะคำนวณ SHA-256 checksum ของไฟล์ใน Python ได้อย่างไร?
เปิดไฟล์ในโหมด binary และส่งข้อมูลไปยัง hasher เป็นชิ้นๆ ด้วย .update() บน Python 3.11+ ใช้ hashlib.file_digest() ซึ่งมี API ที่ง่ายกว่า อย่าเรียก f.read() กับไฟล์ขนาดใหญ่ เพราะจะโหลดไฟล์ทั้งหมดเข้าหน่วยความจำ
import hashlib
def sha256_file(path: str) -> str:
h = hashlib.sha256()
with open(path, "rb") as f:
for chunk in iter(lambda: f.read(8192), b""):
h.update(chunk)
return h.hexdigest()
print(sha256_file("release-v4.2.1.tar.gz"))จะสร้าง HMAC-SHA256 signature ใน Python ได้อย่างไร?
ใช้ hmac module พร้อม hashlib.sha256 เป็น digestmod ส่งคีย์ลับและข้อความเป็น bytes ผลลัพธ์คือ keyed hash ที่พิสูจน์ทั้งความสมบูรณ์และความถูกต้อง — ผู้รับต้องใช้คีย์เดียวกันในการตรวจสอบ
import hmac
import hashlib
secret = b"webhook_secret_9f3a"
payload = b'{"event":"payment.completed","amount":4999}'
signature = hmac.new(secret, payload, hashlib.sha256).hexdigest()
print(signature) # 64-char hex HMACจะตรวจสอบว่า string เป็น SHA-256 hex digest ที่ถูกต้องได้อย่างไร?
SHA-256 hex digest ประกอบด้วยอักขระ hexadecimal ครบ 64 ตัว ใช้ regex หรือการตรวจสอบความยาวและอักขระอย่างง่าย วิธี regex อ่านง่ายที่สุด
import re
def is_sha256(s: str) -> bool:
return bool(re.fullmatch(r"[a-fA-F0-9]{64}", s))
print(is_sha256("e3b0c44298fc1c149afbf4c8996fb924"
"27ae41e4649b934ca495991b7852b855")) # True
print(is_sha256("not-a-hash")) # Falseเครื่องมือที่เกี่ยวข้อง
Dmitri is a DevOps engineer who relies on Python as his primary scripting and automation language. He builds internal tooling, CI/CD pipelines, and infrastructure automation scripts that run in production across distributed teams. He writes about the Python standard library, subprocess management, file processing, encoding utilities, and the practical shell-adjacent Python that DevOps engineers use every day.
Maria is a backend developer specialising in Python and API integration. She has broad experience with data pipelines, serialisation formats, and building reliable server-side services. She is an active member of the Python community and enjoys writing practical, example-driven guides that help developers solve real problems without unnecessary theory.