Hash SHA-256 Python โ Panduan hashlib + Contoh Kode
Gunakan Generator Hash SHA-256 gratis langsung di browser Anda โ tidak perlu instalasi.
Coba Generator Hash SHA-256 Online โSetiap pipeline deployment yang pernah saya bangun pada akhirnya membutuhkan verifikasi checksum file, penandatanganan payload webhook, atau fingerprinting cache key. SHA-256 hashing Python dengan modul hashlib bawaan menangani semua kasus tersebut โ dan sudah terinstal. hashlib.sha256() membungkus implementasi OpenSSL di CPython, sehingga cepat dan FIPS-compliant sejak awal. Untuk hash sekali pakai tanpa menulis kode, SHA-256 hash generator online memberikan hasil secara instan. Semua contoh menargetkan Python 3.9+.
- โhashlib.sha256(data).hexdigest() adalah cara standar untuk meng-hash bytes โ bagian dari stdlib, didukung OpenSSL.
- โString harus di-encode ke bytes terlebih dahulu: hashlib.sha256("text".encode("utf-8")).
- โUntuk checksum file, masukkan potongan via .update() โ jangan pernah membaca file besar ke memori sekaligus.
- โHMAC-SHA256 memerlukan modul hmac: hmac.new(key, msg, hashlib.sha256) โ SHA-256 saja tidak memiliki key.
Apa itu SHA-256 Hashing?
SHA-256 (Secure Hash Algorithm, 256-bit) mengambil input dengan panjang sembarang dan menghasilkan digest tetap 256-bit (32 byte). Input yang sama selalu menghasilkan output yang sama, tetapi bahkan perubahan satu bit pada input menghasilkan hash yang sama sekali berbeda โ properti ini disebut efek avalanche. SHA-256 adalah bagian dari keluarga SHA-2, distandarisasi oleh NIST, dan merupakan tulang punggung fingerprint sertifikat TLS, commit ID Git, header blok Bitcoin, dan verifikasi integritas file. Algoritma ini menggunakan konstruksi Merkle-Damgรฅrd dengan 64 putaran kompresi untuk menghasilkan output 256-bit.
deployment-v4.2.1
a1f7c3d8e9b2...27ae41e4649b (64 hex chars)
Hex digest di atas adalah representasi standar โ 64 karakter heksadesimal, selalu panjang yang sama terlepas dari apakah Anda meng-hash satu byte atau seluruh citra disk.
hashlib.sha256() โ Pendekatan Standard Library
Modul hashlib disertakan dengan setiap instalasi Python โ tidak perlu pip install. Panggil hashlib.sha256() dengan argumen bytes untuk membuat objek hash, lalu ambil hasilnya dengan .hexdigest() (string hex) atau .digest() (raw bytes). Nama fungsi ditulis huruf kecil: sha256, bukan SHA256.
import hashlib # Hash string byte secara langsung digest = hashlib.sha256(b"deployment-v4.2.1").hexdigest() print(digest) # a8f5f167f44f4964e6c998dee827110c3f1de4d0280c68cba98cf70b4b5157db
Kesalahan paling umum dengan hashlib.sha256() adalah melewatkan str bukan bytes. String Python adalah Unicode, dan fungsi hash beroperasi pada raw bytes. Anda harus memanggil .encode("utf-8") sebelum hashing. Ini hampir selalu menjadi masalah pertama kali.
import hashlib
# String harus di-encode ke bytes sebelum hashing
config_key = "redis://cache.internal:6379/0"
digest = hashlib.sha256(config_key.encode("utf-8")).hexdigest()
print(digest)
# 7d3f8c2a1b9e4f5d6c8a7b3e2f1d9c4a5b8e7f6d3c2a1b9e4f5d6c8a7b3e2f1dMethod .update() memungkinkan Anda memasukkan data secara bertahap. Memanggil h.update(a); h.update(b) setara dengan hashlib.sha256(a + b). Inilah cara Anda meng-hash file dalam potongan tanpa memuat seluruh isinya ke dalam memori.
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()) # Setara dengan hashlib.sha256(b"request_id=req_7f3a91bc×tamp=1741614120&amount=4999").hexdigest()
.digest() mengembalikan raw 32 bytes. .hexdigest() mengembalikan string hex 64 karakter. Gunakan .digest() saat memasukkan hasilnya ke HMAC, encoding Base64, atau protokol biner. Gunakan .hexdigest() untuk logging, kolom database, dan perbandingan checksum.HMAC-SHA256 โ Keyed Hashing dengan Modul hmac
SHA-256 saja tidak memiliki konsep secret key โ siapa pun dengan input yang sama dapat menghitung hash yang sama. Jika Anda perlu membuktikan bahwa pesan berasal dari pengirim tertentu (verifikasi webhook, penandatanganan permintaan API, autentikasi token), Anda memerlukan HMAC. Modul hmac adalah bagian dari standard library Python dan membungkus key ke dalam proses hashing sehingga hanya seseorang yang memiliki key tersebut yang dapat menghasilkan atau memverifikasi digest yang sama.
import hmac
import hashlib
# Verifikasi tanda tangan webhook
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 digestMemverifikasi HMAC yang masuk memerlukan hmac.compare_digest() bukan operator ==. Operator kesetaraan rentan terhadap timing attack โ ia berhenti pada byte pertama yang tidak cocok, dan penyerang dapat mengukur waktu respons untuk menebak tanda tangan yang benar byte demi byte. compare_digest() berjalan dalam waktu konstan terlepas dari di mana ketidakcocokan terjadi.
import hmac
import hashlib
def verify_webhook(payload: bytes, received_sig: str, secret: bytes) -> bool:
"""Verifikasi tanda tangan webhook menggunakan perbandingan constant-time."""
expected = hmac.new(secret, payload, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, received_sig)
# Simulasi verifikasi webhook gaya Stripe
incoming_payload = b'{"event":"payment.completed","amount":4999}'
incoming_signature = "a1b2c3d4e5f6..." # dari header X-Signature
webhook_secret = b"whsec_9f3a7b2e1d4c"
if verify_webhook(incoming_payload, incoming_signature, webhook_secret):
print("Tanda tangan valid โ proses event")
else:
print("Tanda tangan tidak cocok โ tolak permintaan")Penandatanganan Permintaan HMAC-SHA256
Penandatanganan permintaan API mengikuti prinsip yang sama: buat canonical string dari komponen permintaan (method, path, timestamp, body hash) dan tandatangani dengan secret key. AWS Signature V4, Stripe, dan webhook GitHub semuanya menggunakan variasi pola ini.
import hmac
import hashlib
import time
def sign_request(method: str, path: str, body: bytes, secret: bytes) -> str:
"""Buat tanda tangan HMAC-SHA256 untuk permintaan API."""
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}"
# Penggunaan
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...HMAC-SHA256 dengan Encoding Base64
Beberapa API (AWS Signature V4, berbagai payment gateway) mengharapkan hasil HMAC sebagai string Base64 bukan hex. Perbedaannya: hex menggunakan 64 karakter, Base64 menggunakan 44 karakter untuk digest 32 byte yang sama.
import hmac
import hashlib
import base64
secret = b"webhook_secret_9f3a"
message = b"POST /api/v2/events 1741614120"
# Output hex: 64 karakter
hex_sig = hmac.new(secret, message, hashlib.sha256).hexdigest()
print(f"Hex: {hex_sig}")
# Output Base64: 44 karakter (lebih pendek, umum di HTTP header)
raw_sig = hmac.new(secret, message, hashlib.sha256).digest()
b64_sig = base64.b64encode(raw_sig).decode("ascii")
print(f"Base64: {b64_sig}")Hashing datetime, UUID, dan Objek Kustom
SHA-256 beroperasi pada raw bytes, sehingga tipe non-bytes โ datetime, UUID, dataclass, model Pydantic โ harus diserialisasi ke bytes sebelum hashing. Tidak ada konversi otomatis; Anda memilih representasi kanonik. Untuk hashing deterministik lintas sistem, selalu gunakan encoding yang eksplisit dan format serialisasi yang stabil (ISO 8601 untuk datetime, bentuk string standar untuk UUID, JSON dengan kunci terurut untuk dict).
import hashlib
import uuid
from datetime import datetime, timezone
# datetime โ gunakan ISO 8601 dengan offset UTC eksplisit untuk portabilitas
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 โ hash bentuk string kanonik (huruf kecil, dengan tanda hubung)
record_id = uuid.uuid4()
uuid_hash = hashlib.sha256(str(record_id).encode("utf-8")).hexdigest()
print(f"UUID hash: {uuid_hash[:16]}...")Untuk objek kustom, serialisasi ke representasi bytes kanonik sebelum hashing. JSON dengan kunci terurut cocok untuk objek seperti 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:
"""Hash instance dataclass menggunakan JSON kunci terurut untuk determinisme."""
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)) # stabil di semua run dan mesinsort_keys=True) saat meng-hash objek yang diserialisasi JSON. Urutan penyisipan dict dipertahankan di Python 3.7+ tetapi dapat berbeda antar jalur serialisasi, menghasilkan hash berbeda untuk data yang identik.Checksum SHA-256 File โ Verifikasi Unduhan dan Artefak
Menghitung checksum SHA-256 dari sebuah file adalah salah satu penggunaan algoritma yang paling umum. Anda melihatnya di mana-mana: halaman rilis untuk binary Go, file wheel Python, manifes Docker image, pembaruan firmware. Kuncinya adalah membaca file dalam potongan daripada memuat semuanya sekaligus โ citra ISO 2 GB tidak seharusnya memerlukan 2 GB RAM hanya untuk meng-hash-nya.
import hashlib
def sha256_checksum(filepath: str, chunk_size: int = 8192) -> str:
"""Hitung hash SHA-256 dari sebuah file, membaca per potongan untuk menghemat memori."""
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()
# Hash artefak rilis
checksum = sha256_checksum("/tmp/release-v4.2.1.tar.gz")
print(f"SHA-256: {checksum}")Python 3.11 menambahkan hashlib.file_digest() yang melakukan pembacaan per potongan secara internal dan mungkin menggunakan optimasi zero-copy di platform yang didukung. Jika Anda menggunakan 3.11 atau lebih baru, lebih baik gunakan itu daripada 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())Verifikasi File yang Diunduh Terhadap Checksum yang Diketahui
import hashlib
import hmac as hmac_mod # hanya untuk compare_digest
def verify_checksum(filepath: str, expected_hex: str) -> bool:
"""Verifikasi checksum SHA-256 menggunakan perbandingan 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())
# Verifikasi artefak rilis
expected = "a8f5f167f44f4964e6c998dee827110c3f1de4d0280c68cba98cf70b4b5157db"
if verify_checksum("/tmp/release-v4.2.1.tar.gz", expected):
print("Checksum cocok โ file utuh")
else:
print("Checksum tidak cocok โ file mungkin rusak atau dimodifikasi")hmac.compare_digest() untuk perbandingan checksum, bahkan jika tidak ada secret key. Perbandingan constant-time mencegah kebocoran informasi berbasis timing. Operator == berfungsi secara fungsional tetapi tidak aman untuk konteks yang sensitif terhadap keamanan.SHA-256 dengan Encoding Base64
Beberapa protokol mengharapkan SHA-256 digest sebagai string Base64 bukan hex. HTTP header seperti Content-Digest dan Integrity (Subresource Integrity di browser) menggunakan Base64, dan tanda tangan JWT di-encode dalam Base64url. Triknya adalah menggunakan Base64 pada raw bytes dari .digest(), bukan string hex.
import hashlib
import base64
data = b"integrity check payload"
# Benar: Base64 dari raw bytes (32 byte โ 44 karakter Base64)
raw_digest = hashlib.sha256(data).digest()
b64_digest = base64.b64encode(raw_digest).decode("ascii")
print(f"sha256-{b64_digest}")
# sha256-<44 karakter>
# Salah: Base64 dari string hex (64 byte ASCII โ 88 karakter Base64 โ dua kali lipat ukuran)
hex_digest = hashlib.sha256(data).hexdigest()
wrong = base64.b64encode(hex_digest.encode()).decode()
print(f"Panjang salah: {len(wrong)} karakter") # 88 โ bukan yang diharapkan API.digest(), bukan .hexdigest(), sebelum encoding Base64.Referensi hashlib.sha256()
Konstruktor dan method pada objek hash SHA-256:
Parameter hmac.new() untuk keyed hashing:
Library cryptography โ Alternatif API SHA-256
Paket cryptography menyediakan API berbeda untuk SHA-256 melalui primitif hazmat-nya. Saya jarang menggunakannya ketika yang saya butuhkan hanyalah hash โ hashlib lebih sederhana dan tidak memiliki dependensi eksternal. Tetapi jika proyek Anda sudah bergantung pada cryptography untuk TLS, X.509, atau enkripsi simetris, menggunakan API hash-nya membuat semuanya berada di satu library dan memberikan penanganan error yang konsisten.
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()) # string hex 64 karakter # a8f5f167f44f4964e6c998dee827110c3f1de4d0280c68cba98cf70b4b5157db
cryptography memerlukan pip install cryptography. Objek hash hanya dapat digunakan sekali: memanggil .finalize() untuk kedua kali akan memunculkan AlreadyFinalized. Gunakan .copy() sebelum finalisasi jika Anda perlu percabangan status hash.Hash Data dari File dan Respons API
Dua skenario yang sering muncul: meng-hash file di disk untuk memverifikasi artefak rilis, dan meng-hash body respons HTTP untuk digunakan sebagai cache key atau memverifikasi webhook.
Baca File โ Hitung SHA-256 โ Bandingkan
import hashlib
import sys
def hash_file_safe(filepath: str) -> str | None:
"""Hash file dengan penanganan error yang tepat."""
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"Error: {filepath} tidak ditemukan", file=sys.stderr)
return None
except PermissionError:
print(f"Error: tidak ada izin baca untuk {filepath}", file=sys.stderr)
return None
result = hash_file_safe("/etc/nginx/nginx.conf")
if result:
print(f"SHA-256: {result}")Respons HTTP โ Hash Body untuk Cache Key
import hashlib
import urllib.request
import json
def fetch_and_hash(url: str) -> tuple[dict, str]:
"""Ambil JSON dari API dan kembalikan data beserta hash SHA-256-nya."""
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"Gagal mengambil {url}: {exc}") from exc
# Cache key berdasarkan konten respons
data, digest = fetch_and_hash("https://api.exchange.internal/v2/rates")
print(f"Hash respons: {digest[:16]}...")
print(f"EUR/USD: {data.get('rates', {}).get('EUR', 'N/A')}")Untuk pemeriksaan sekali pakai yang cepat, SHA-256 generator ToolDeck berjalan sepenuhnya di browser Anda โ tidak perlu kode.
SHA-256 Hashing via Command Line
Terkadang Anda hanya perlu hash cepat di terminal selama insiden atau deployment. Modul hashlib Python tidak memiliki subperintah CLI bawaan (berbeda dengan python3 -m json.tool), tetapi Anda dapat menggunakan one-liner atau alat sistem.
# 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 (lintas platform) echo -n "deployment-v4.2.1" | openssl dgst -sha256
# Hash tarball rilis sha256sum release-v4.2.1.tar.gz # atau openssl dgst -sha256 release-v4.2.1.tar.gz # Verifikasi terhadap checksum yang diketahui echo "a8f5f167f44f4964e6c998dee827110c release-v4.2.1.tar.gz" | sha256sum -c - # release-v4.2.1.tar.gz: OK
echo -n (tanpa newline di akhir) saat meng-hash string di command line. echo biasa menambahkan \n, yang mengubah hash. Ini adalah alasan utama mengapa orang mendapatkan hash yang berbeda antara Python dan shell.Alternatif Performa Tinggi โ hashlib dengan OpenSSL dan pycryptodome
Di CPython, hashlib.sha256() sudah mendelegasikan ke implementasi C OpenSSL, sehingga cepat โ biasanya 500+ MB/s di perangkat keras modern.
Jika SHA-256 hashing muncul di profiler Anda โ misalnya Anda menghitung checksum untuk ribuan file dalam pipeline CI atau meng-hash setiap body permintaan di API gateway bervolume tinggi โ ada dua pilihan: optimalkan pola pemanggilan hashlib, atau beralih ke pycryptodome untuk API crypto terpadu yang juga mencakup SHA-3 dan BLAKE2:
pip install pycryptodome
from Crypto.Hash import SHA256 h = SHA256.new() h.update(b"deployment-v4.2.1") print(h.hexdigest()) # a8f5f167f44f4964e6c998dee827110c3f1de4d0280c68cba98cf70b4b5157db
Untuk hashing file paralel bervolume tinggi, keuntungan lebih besar datang dari pengurangan overhead Python melalui ukuran potongan yang lebih besar dan threading:
import hashlib
import os
from pathlib import Path
from concurrent.futures import ThreadPoolExecutor
def hash_file(path: Path) -> tuple[str, str]:
"""Hash satu file dan kembalikan (path, hex digest)."""
h = hashlib.sha256()
with open(path, "rb") as f:
for chunk in iter(lambda: f.read(65536), b""): # potongan 64 KB
h.update(chunk)
return str(path), h.hexdigest()
def hash_directory(directory: str, pattern: str = "*.tar.gz") -> dict[str, str]:
"""Hash semua file yang cocok secara paralel menggunakan 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
# Hash semua artefak rilis secara paralel
checksums = hash_directory("/var/releases", "*.tar.gz")
for path, digest in checksums.items():
print(f"{digest} {path}")Menggunakan potongan 64 KB bukan 8 KB mengurangi jumlah panggilan Python-ke-C sebanyak 8x. Thread bekerja baik di sini karena GIL dilepas selama hashing di level C โ bottleneck-nya adalah disk I/O, bukan CPU.
Output Terminal dengan Syntax Highlighting
Library rich berguna saat Anda perlu memverifikasi sekumpulan file dan menginginkan tabel yang menampilkan status lulus/gagal per file daripada output hex mentah yang terus bergulir.
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:
"""Hash file dan tampilkan hasil dengan verifikasi berkode warna."""
table = Table(title="Verifikasi SHA-256")
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]โ TIDAK COCOK[/red]"
table.add_row(name, f"{digest[:16]}...", status)
console.print(table)
# Penggunaan
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) atau arahkan ke file dengan Console(file=open(...)).Bekerja dengan File Besar
Pola .update() per potongan menangani file dengan ukuran apapun dengan penggunaan memori yang konstan. Untuk file yang sangat besar (citra disk multi-GB, backup database), perhatian utama bergeser dari memori ke umpan balik pengguna โ meng-hash 10 GB dengan kecepatan 500 MB/s tetap membutuhkan 20 detik, dan keheningan selama itu membuat orang gelisah.
import hashlib
import os
def sha256_with_progress(filepath: str) -> str:
"""Hash file besar dengan laporan progres ke 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): # potongan 1 MB
h.update(chunk)
bytes_read += len(chunk)
pct = (bytes_read / file_size) * 100
print(f"\r Hashing: {pct:.1f}% ({bytes_read >> 20} MB / {file_size >> 20} MB)",
end="", flush=True)
print() # newline setelah progres
return h.hexdigest()
digest = sha256_with_progress("/mnt/backups/db-snapshot-2026-03.sql.gz")
print(f"SHA-256: {digest}")NDJSON / JSON Lines โ Hash Setiap Record Secara Terpisah
import hashlib
import json
def hash_ndjson_records(filepath: str) -> dict[str, str]:
"""Hash setiap record JSON dalam file NDJSON untuk deduplikasi."""
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)
# Normalisasi sebelum hashing: urutkan kunci untuk output deterministik
canonical = json.dumps(record, sort_keys=True, separators=(",", ":"))
digest = hashlib.sha256(canonical.encode("utf-8")).hexdigest()
if digest in seen:
print(f"Baris {line_num}: duplikat dari baris {seen[digest]}")
else:
seen[digest] = line_num
except json.JSONDecodeError:
print(f"Baris {line_num}: JSON tidak valid, dilewati")
print(f"Diproses {line_num} baris, {len(seen)} record unik")
return seen
hash_ndjson_records("telemetry-events-2026-03.ndjson")hashlib.sha256(data) satu kali ke loop .update() per potongan saat file melebihi 50โ100 MB. Di bawah ambang batas tersebut, membaca seluruh file dengan f.read() tidak masalah โ penggunaan memori akan kurang lebih sama dengan ukuran file.Kesalahan Umum
Masalah: hashlib.sha256('text') memunculkan TypeError: Unicode-objects must be encoded before hashing. Fungsi ini memerlukan bytes, bukan str.
Solusi: Encode string terlebih dahulu: hashlib.sha256('text'.encode('utf-8')). Atau gunakan literal b'' untuk nilai yang hardcoded.
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()
# Berhasil โ mengembalikan string hex 64 karakterMasalah: Operator == berhenti pada byte pertama yang tidak cocok. Penyerang dapat mengukur waktu respons untuk menebak tanda tangan yang benar satu byte setiap saat.
Solusi: Gunakan hmac.compare_digest() untuk semua perbandingan yang sensitif terhadap keamanan โ ia berjalan dalam waktu konstan terlepas dari di mana ketidakcocokan terjadi.
received_sig = request.headers["X-Signature"]
expected_sig = hmac.new(key, body, hashlib.sha256).hexdigest()
if received_sig == expected_sig: # rentan terhadap 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)Masalah: base64.b64encode(digest.hexdigest().encode()) menghasilkan string 88 karakter โ dua kali lipat dari 44 karakter yang diharapkan. API yang mengharapkan SHA-256 berbasis Base64 akan menolaknya.
Solusi: Panggil .digest() (raw bytes) sebelum encoding Base64, bukan .hexdigest() (string hex).
import hashlib, base64 hex_str = hashlib.sha256(data).hexdigest() b64 = base64.b64encode(hex_str.encode()) # 88 karakter โ salah!
import hashlib, base64 raw = hashlib.sha256(data).digest() b64 = base64.b64encode(raw) # 44 karakter โ benar
Masalah: hashlib.sha256(open('large.iso', 'rb').read()) memuat seluruh file ke memori. File 4 GB memerlukan 4 GB RAM hanya untuk komputasi hash.
Solusi: Baca per potongan dengan loop dan .update(). Penggunaan memori tetap konstan terlepas dari ukuran file.
import hashlib
# Memuat seluruh file 4 GB ke memori
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() # penggunaan memori konstanhashlib vs hmac vs Alternatif โ Perbandingan Cepat
Untuk hashing sederhana โ checksum, cache key, fingerprinting konten โ tetap gunakan hashlib.sha256(). Beralih ke hmac.new() saat Anda memerlukan secret key (webhook, tanda tangan API, autentikasi token). Gunakan library cryptography hanya jika proyek Anda sudah menggunakannya untuk enkripsi atau TLS โ menambahkan dependensi ekstensi C hanya untuk hashing adalah berlebihan ketika hashlib sudah didukung oleh OpenSSL.
Bisakah SHA-256 Didekripsi? โ Hashing vs Enkripsi
Jawaban singkat: tidak. SHA-256 adalah fungsi satu arah. Algoritma ini dirancang untuk tidak dapat dibalik โ Anda tidak dapat merekonstruksi input asli dari digest 256-bit. Ini bukan keterbatasan implementasi; ini adalah properti matematis dari fungsi hash. Ruang output 256-bit sangat besar (2256 kemungkinan nilai), dan fungsi ini membuang informasi selama 64 putaran kompresinya.
Penyerang dapat mencoba serangan brute-force atau kamus terhadap input yang lemah (kata sandi umum, string pendek), tetapi untuk input dengan entropi yang memadai โ API key, token acak, konten file โ membalikkan SHA-256 tidak layak secara komputasi dengan perangkat keras saat ini. Jika Anda memerlukan transformasi yang dapat dibalik, gunakan enkripsi simetris:
# Hashing โ satu arah, tidak bisa mendapatkan kembali nilai asli import hashlib digest = hashlib.sha256(b"secret-config-value").hexdigest() # Tidak ada cara untuk mendapatkan kembali "secret-config-value" dari digest # Enkripsi โ dua arah, bisa didekripsi dengan 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" โ nilai asli dipulihkan
Untuk cara tanpa instalasi untuk dengan cepat menghasilkan hash SHA-256, alat online berjalan sepenuhnya di browser Anda.
Cara Memeriksa apakah String adalah Hash SHA-256 yang Valid di Python
SHA-256 hex digest yang valid adalah tepat 64 karakter heksadesimal (0-9, a-f, A-F). Validasi cepat sebelum memproses input yang tidak dipercaya mencegah kesalahan yang membingungkan di hilir.
import re
def is_sha256_hex(value: str) -> bool:
"""Periksa apakah string cocok dengan format SHA-256 hex digest."""
return bool(re.fullmatch(r"[a-fA-F0-9]{64}", value))
# Kasus uji
print(is_sha256_hex("e3b0c44298fc1c149afbf4c8996fb924"
"27ae41e4649b934ca495991b7852b855")) # True โ SHA-256 dari string kosong
print(is_sha256_hex("e3b0c44298fc1c14")) # False โ terlalu pendek
print(is_sha256_hex("zzzz" * 16)) # False โ karakter hex tidak validPertanyaan yang Sering Diajukan
Bagaimana cara meng-hash string dengan SHA-256 di Python?
Panggil hashlib.sha256() dengan string yang di-encode ke bytes. String di Python adalah Unicode, dan fungsi hash beroperasi pada raw bytes, sehingga Anda harus memanggil .encode("utf-8") terlebih dahulu. Method .hexdigest() mengembalikan string hex 64 karakter yang umum digunakan.
import hashlib
api_key = "sk_live_9f3a7b2e1d4c"
digest = hashlib.sha256(api_key.encode("utf-8")).hexdigest()
print(digest)
# e3b7c4a1f8d2...64 hex charactersBisakah hash SHA-256 didekripsi kembali ke teks aslinya?
Tidak. SHA-256 adalah fungsi satu arah โ ia memetakan input dengan panjang sembarang ke output 256-bit tetap dan membuang struktur dalam prosesnya. Tidak ada invers matematis. Penyerang dapat mencoba serangan brute-force atau rainbow table terhadap input yang lemah (kata sandi pendek, kata umum), tetapi untuk input dengan entropi yang memadai, membalikkan SHA-256 tidak layak secara komputasi. Jika Anda membutuhkan transformasi yang dapat dibalik, gunakan enkripsi (AES-GCM, Fernet) bukan hashing.
Apa perbedaan antara .digest() dan .hexdigest()?
.digest() mengembalikan raw 32 byte dari hash sebagai objek bytes. .hexdigest() mengembalikan data yang sama yang di-encode sebagai string heksadesimal huruf kecil 64 karakter. Gunakan .digest() saat Anda membutuhkan output biner โ dimasukkan ke HMAC, encoding Base64, atau penulisan ke protokol biner. Gunakan .hexdigest() saat Anda membutuhkan string yang dapat dibaca manusia untuk logging, penyimpanan database, atau perbandingan checksum.
import hashlib h = hashlib.sha256(b"deployment-v4.2.1") print(len(h.digest())) # 32 (bytes) print(len(h.hexdigest())) # 64 (hex characters)
Bagaimana cara menghitung checksum SHA-256 dari sebuah file di Python?
Buka file dalam mode biner dan masukkan ke hasher dalam potongan dengan .update(). Pada Python 3.11+, gunakan hashlib.file_digest() untuk API yang lebih sederhana. Jangan pernah memanggil f.read() pada file besar โ itu akan memuat seluruh file ke dalam memori.
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"))Bagaimana cara membuat tanda tangan HMAC-SHA256 di Python?
Gunakan modul hmac dengan hashlib.sha256 sebagai digestmod. Berikan secret key dan pesan sebagai bytes. Hasilnya adalah hash berkunci yang membuktikan integritas dan keaslian โ penerima membutuhkan key yang sama untuk memverifikasi.
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 HMACBagaimana cara memvalidasi apakah sebuah string adalah SHA-256 hex digest yang valid?
SHA-256 hex digest adalah tepat 64 karakter heksadesimal. Gunakan regex atau pemeriksaan panjang + karakter sederhana. Pendekatan regex adalah yang paling mudah dibaca.
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")) # FalseAlat Terkait
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.