ToolDeck

Python SHA-256 ด้วย hashlib

·DevOps Engineer & Python Automation Specialist·ตรวจสอบโดยMaria Santos·เผยแพร่เมื่อ

ใช้ เครื่องสร้าง 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 บิต

Before · text
After · text
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

Python 3.9+ — minimal SHA-256 hash
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") ก่อนการแฮช ข้อผิดพลาดนี้เกิดขึ้นกับเกือบทุกคนในครั้งแรก

Python 3.9+ — hashing a string
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) นี่คือวิธีการแฮชไฟล์เป็นชิ้นๆ โดยไม่โหลดเนื้อหาทั้งหมดเข้าหน่วยความจำ

Python 3.9+ — incremental hashing with update()
import hashlib

h = hashlib.sha256()
h.update(b"request_id=req_7f3a91bc")
h.update(b"&timestamp=1741614120")
h.update(b"&amount=4999")
print(h.hexdigest())
# Equivalent to hashlib.sha256(b"request_id=req_7f3a91bc&timestamp=1741614120&amount=4999").hexdigest()
หมายเหตุ:.digest() คืนค่า 32 bytes ดิบ .hexdigest() คืนค่า hex string 64 ตัวอักษร ใช้ .digest() เมื่อต้องส่งผลลัพธ์เข้า HMAC, การเข้ารหัส Base64 หรือ binary protocol ใช้ .hexdigest() สำหรับ logging, คอลัมน์ในฐานข้อมูล และการเปรียบเทียบ checksum

HMAC-SHA256 — Keyed Hashing ด้วย hmac Module

SHA-256 ลำพังไม่มีแนวคิดเรื่องคีย์ลับ — ใครก็ตามที่มี input เดียวกันสามารถคำนวณ hash เดียวกันได้ หากต้องการพิสูจน์ว่าข้อความมาจากผู้ส่งที่เฉพาะเจาะจง (webhook verification, API request signing, token authentication) คุณต้องการ HMAC Module hmac เป็นส่วนหนึ่งของ standard library ของ Python และรวมคีย์เข้าสู่กระบวนการแฮช เพื่อให้เฉพาะผู้ที่มีคีย์เท่านั้นที่สามารถสร้างหรือตรวจสอบ digest เดียวกันได้

Python 3.9+ — basic HMAC-SHA256
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() ทำงานในเวลาคงที่โดยไม่คำนึงว่าความไม่ตรงกันเกิดขึ้นที่ไหน

Python 3.9+ — verify a webhook signature
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 ล้วนใช้รูปแบบนี้ในรูปแบบต่างๆ

Python 3.9+ — sign an API request with HMAC-SHA256
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 เดียวกัน

Python 3.9+ — Base64-encoded HMAC-SHA256
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)

Python 3.9+ — hash a datetime and UUID
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:

Python 3.9+ — hash a custom object
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 key เสมอ (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 เพียงเพื่อแฮชมัน

Python 3.9+ — SHA-256 checksum of a file (chunked)
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

Python 3.11+ — hashlib.file_digest()
import hashlib

with open("/tmp/release-v4.2.1.tar.gz", "rb") as f:
    digest = hashlib.file_digest(f, "sha256")

print(digest.hexdigest())

ตรวจสอบไฟล์ที่ดาวน์โหลดกับ Checksum ที่รู้จัก

Python 3.9+ — checksum verification
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

Python 3.9+ — Base64-encoded SHA-256
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 คาดหวัง
คำเตือน:การ Base64-encode hex string แทนที่จะเป็น bytes ดิบเป็นข้อผิดพลาดที่พบบ่อย ทำให้ได้ output ที่ยาวเป็นสองเท่าของที่คาดหวัง API จะปฏิเสธ และข้อความ error มักไม่บอกว่าเกิดจากสาเหตุนี้ ให้เรียก .digest() เสมอ ไม่ใช่ .hexdigest() ก่อน Base64 encoding

hashlib.sha256() Reference

constructor และเมธอดบน SHA-256 hash object:

Parameter / Method
Type
คำอธิบาย
data (positional)
bytes
ข้อมูลเริ่มต้นสำหรับการแฮช — เทียบเท่ากับการเรียก update(data) ทันทีหลังจากสร้าง object
.update(data)
bytes
เพิ่ม bytes เข้าสู่สถานะของ hash — สามารถเรียกได้หลายครั้งสำหรับข้อมูลที่ส่งมาเป็นชิ้นๆ
.digest()
→ bytes
คืนค่า binary digest ขนาด 32 bytes — ใช้สำหรับ HMAC, binary protocol และการเข้ารหัส Base64
.hexdigest()
→ str
คืนค่า hex string 64 ตัวอักษรพิมพ์เล็ก — รูปแบบมาตรฐานสำหรับ checksum และการตรวจสอบ
.copy()
→ hash object
คืนค่าสำเนาของสถานะ hash ปัจจุบัน — ช่วยให้แตกสาขา digest ได้โดยไม่ต้องแฮชใหม่ตั้งแต่ต้น
hashlib.sha256()
constructor
สร้าง SHA-256 hash object ใหม่โดยใช้ OpenSSL บน CPython — usedfips=True บน 3.9+ จำกัดเฉพาะอัลกอริทึมที่ผ่าน FIPS

parameter ของ hmac.new() สำหรับ keyed hashing:

Parameter
Type
คำอธิบาย
key
bytes
คีย์ลับ — ต้องเป็น bytes ไม่ใช่ str
msg
bytes | None
ข้อความเริ่มต้นสำหรับการยืนยัน — ค่าเริ่มต้นเป็น None สามารถเรียก update() ภายหลังได้
digestmod
str | callable
อัลกอริทึม hash: ส่ง hashlib.sha256 หรือ string "sha256"

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 ที่สอดคล้องกัน

Python 3.9+ — SHA-256 with the cryptography library
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
คำเตือน:library cryptography ต้องการ pip install cryptography hash object ใช้ได้ครั้งเดียว: การเรียก .finalize() ครั้งที่สองจะเกิด AlreadyFinalized ใช้ .copy() ก่อน finalize หากต้องการแตกสาขาสถานะ hash

แฮชข้อมูลจากไฟล์และ API Response

สองสถานการณ์ที่พบบ่อยคือ: การแฮชไฟล์บน disk เพื่อตรวจสอบ release artifact และการแฮช HTTP response body เพื่อใช้เป็น cache key หรือตรวจสอบ webhook

อ่านไฟล์ → คำนวณ SHA-256 → เปรียบเทียบ

Python 3.9+ — hash a config backup with error handling
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

Python 3.9+ — hash an API response
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 ได้

bash — hash a string from the command line
# 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
bash — hash a file
# แฮช 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 ด้วย:

bash — install pycryptodome
pip install pycryptodome
Python 3.9+ — SHA-256 with 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:

Python 3.9+ — batch file hashing with hashlib
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 ที่เลื่อนผ่าน

bash — install rich
pip install rich
Python 3.9+ — rich output for hash verification
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,
)
หมายเหตุ:Rich output ใช้สำหรับแสดงผลใน terminal เท่านั้น อย่าเขียน ANSI escape code ลงใน log file หรือ API response — ลบออกด้วย console.print(data, highlight=False) หรือเปลี่ยนเส้นทาง ไปยังไฟล์ด้วย Console(file=open(...))

การทำงานกับไฟล์ขนาดใหญ่

รูปแบบ .update() แบบชิ้นๆ จัดการไฟล์ขนาดใดก็ได้ด้วยการใช้หน่วยความจำคงที่ สำหรับไฟล์ขนาดใหญ่มาก (disk image หลาย GB, database backup) ความกังวลหลักเปลี่ยนจากหน่วยความจำเป็นการแสดงผลให้ผู้ใช้ — การแฮช 10 GB ที่ 500 MB/s ยังใช้เวลา 20 วินาที และความเงียบในช่วงนั้นทำให้คนกังวล

Python 3.9+ — hash large files with progress reporting
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 แยกกัน

Python 3.9+ — hash individual records in an NDJSON stream
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() ก็ใช้ได้ — การใช้หน่วยความจำจะเท่ากับขนาดไฟล์โดยประมาณ

ข้อผิดพลาดที่พบบ่อย

ส่ง str แทน bytes ให้ hashlib.sha256()

ปัญหา: hashlib.sha256('text') เกิด TypeError: Unicode-objects must be encoded before hashing ฟังก์ชันต้องการ bytes ไม่ใช่ str

วิธีแก้ไข: Encode string ก่อน: hashlib.sha256('text'.encode('utf-8')) หรือใช้ b'' literal สำหรับค่าที่กำหนดไว้ตายตัว

Before · Python
After · Python
import hashlib
digest = hashlib.sha256("deployment-v4.2.1").hexdigest()
# TypeError: Unicode-objects must be encoded before hashing
import hashlib
digest = hashlib.sha256("deployment-v4.2.1".encode("utf-8")).hexdigest()
# ใช้งานได้ — คืนค่า hex string 64 ตัวอักษร
ใช้ == แทน hmac.compare_digest() สำหรับการตรวจสอบ signature

ปัญหา: ตัวดำเนินการ == หยุดทำงานเมื่อพบ byte ที่ไม่ตรงกันตัวแรก ผู้โจมตีสามารถวัดเวลาตอบสนองเพื่อเดา signature ที่ถูกต้องทีละ byte

วิธีแก้ไข: ใช้ hmac.compare_digest() สำหรับการเปรียบเทียบที่เกี่ยวข้องกับความปลอดภัยทั้งหมด — ทำงานในเวลาคงที่โดยไม่คำนึงว่าความไม่ตรงกันเกิดขึ้นที่ไหน

Before · Python
After · Python
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-encode hex string แทน bytes ดิบ

ปัญหา: base64.b64encode(digest.hexdigest().encode()) สร้าง string 88 ตัวอักษร — เป็นสองเท่าของ 44 ตัวอักษรที่คาดหวัง API ที่คาดหวัง Base64-encoded SHA-256 จะปฏิเสธ

วิธีแก้ไข: เรียก .digest() (bytes ดิบ) ก่อน Base64-encoding ไม่ใช่ .hexdigest() (hex string)

Before · Python
After · Python
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() การใช้หน่วยความจำคงที่โดยไม่คำนึงถึงขนาดไฟล์

Before · Python
After · Python
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 ทางเลือกอื่น — เปรียบเทียบอย่างย่อ

Method
Output
มีคีย์
ความเร็ว
File Streaming
ต้องติดตั้ง
Custom Types
hashlib.sha256()
hex / bytes
เร็ว (C/OpenSSL)
✓ ผ่าน update()
ไม่ต้อง (stdlib)
encode() เอง
hmac.new()
hex / bytes
เร็ว (C/OpenSSL)
✓ ผ่าน update()
ไม่ต้อง (stdlib)
encode() เอง
hashlib.file_digest()
hex / bytes
เร็ว (zero-copy)
✓ (built-in)
ไม่ต้อง (3.11+)
encode() เอง
cryptography hashes.SHA256()
bytes
เร็ว (OpenSSL)
✓ ผ่าน update()
pip install
encode() เอง
subprocess openssl dgst
hex string
✗ / ✓
ช้ากว่า (fork)
✓ (ระดับ OS)
System openssl
encode() เอง
pyhashcat / custom
varies
เร่งด้วย GPU
pip install
encode() เอง

สำหรับการแฮชทั่วไป — 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:

Python 3.9+ — encryption vs hashing
# 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

Python 3.9+ — validate SHA-256 format
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 ไม่ถูกต้อง
หมายเหตุ:การตรวจสอบนี้ยืนยันรูปแบบเท่านั้น ไม่ใช่ว่า hash ถูกคำนวณมาจาก input ใดเป็นพิเศษ ไม่มีทางบอกได้ว่า hex string 64 ตัวอักษรเป็น SHA-256 digest "จริง" หรือแค่ hex สุ่ม — output ของ SHA-256 ไม่สามารถแยกแยะจากข้อมูลสุ่มได้โดยหลักการออกแบบ

คำถามที่พบบ่อย

จะแฮช string ด้วย SHA-256 ใน Python ได้อย่างไร?

เรียก hashlib.sha256() พร้อม string ที่แปลงเป็น bytes แล้ว string ใน Python เป็น Unicode และฟังก์ชัน hash ทำงานกับ bytes ดิบ จึงต้องเรียก .encode("utf-8") ก่อน เมธอด .hexdigest() จะคืนค่า hex string 64 ตัวอักษรที่คุ้นเคย

Python
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

Python
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() กับไฟล์ขนาดใหญ่ เพราะจะโหลดไฟล์ทั้งหมดเข้าหน่วยความจำ

Python
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 ที่พิสูจน์ทั้งความสมบูรณ์และความถูกต้อง — ผู้รับต้องใช้คีย์เดียวกันในการตรวจสอบ

Python
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 อ่านง่ายที่สุด

Python
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

เครื่องมือที่เกี่ยวข้อง

DV
Dmitri VolkovDevOps Engineer & Python Automation Specialist

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.

MS
Maria Santosผู้ตรวจสอบทางเทคนิค

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.