Spaces:
Sleeping
Sleeping
import streamlit as st | |
import hashlib | |
import pandas as pd | |
import qrcode | |
from io import BytesIO | |
from datetime import datetime | |
import json | |
import base64 | |
# Set page config | |
st.set_page_config( | |
page_title="Document Integrity Checker", | |
page_icon="π", | |
layout="wide" | |
) | |
# Custom CSS | |
st.markdown(""" | |
<style> | |
.stApp { | |
max-width: 1200px; | |
margin: 0 auto; | |
} | |
.status-success { | |
padding: 1rem; | |
border-radius: 4px; | |
background-color: #dcfce7; | |
color: #166534; | |
} | |
.status-error { | |
padding: 1rem; | |
border-radius: 4px; | |
background-color: #fee2e2; | |
color: #991b1b; | |
} | |
.hash-display { | |
font-family: monospace; | |
padding: 1rem; | |
background-color: #f8fafc; | |
border-radius: 4px; | |
} | |
</style> | |
""", unsafe_allow_html=True) | |
def calculate_hash(file_bytes): | |
"""Calculate SHA-256 hash of file""" | |
sha256_hash = hashlib.sha256() | |
sha256_hash.update(file_bytes) | |
return sha256_hash.hexdigest() | |
def generate_qr(data): | |
"""Generate QR code for hash""" | |
qr = qrcode.QRCode(version=1, box_size=10, border=5) | |
qr.add_data(data) | |
qr.make(fit=True) | |
img = qr.make_image(fill_color="black", back_color="white") | |
# Convert to bytes | |
buffered = BytesIO() | |
img.save(buffered, format="PNG") | |
return buffered.getvalue() | |
def save_to_history(filename, file_hash): | |
"""Save verification to history""" | |
history = json.loads(st.session_state.get('history', '[]')) | |
history.insert(0, { | |
'filename': filename, | |
'hash': file_hash, | |
'timestamp': datetime.now().isoformat() | |
}) | |
# Keep only last 10 entries | |
history = history[:10] | |
st.session_state['history'] = json.dumps(history) | |
def get_history(): | |
"""Get verification history""" | |
try: | |
return json.loads(st.session_state.get('history', '[]')) | |
except: | |
return [] | |
def main(): | |
# Header | |
st.title("π Document Integrity Checker") | |
st.markdown("Verifikasi & Lindungi Integritas Dokumen Anda dengan SHA-256") | |
# Main content | |
col1, col2 = st.columns([2, 1]) | |
with col1: | |
st.subheader("Upload Document") | |
uploaded_files = st.file_uploader( | |
"Drag and drop files here", | |
accept_multiple_files=True, | |
type=['pdf', 'doc', 'docx', 'txt', 'jpg', 'png'] | |
) | |
if uploaded_files: | |
for uploaded_file in uploaded_files: | |
# Calculate hash | |
file_bytes = uploaded_file.read() | |
file_hash = calculate_hash(file_bytes) | |
# Display hash | |
st.markdown(f"**File:** {uploaded_file.name}") | |
st.markdown(f""" | |
<div class='hash-display'> | |
{file_hash} | |
</div> | |
""", unsafe_allow_html=True) | |
# Generate and display QR | |
qr_code = generate_qr(file_hash) | |
st.image(qr_code, caption="Scan untuk verifikasi hash") | |
# Save to history | |
save_to_history(uploaded_file.name, file_hash) | |
# Verification input | |
expected_hash = st.text_input("Masukkan hash untuk verifikasi:", key=f"verify_{uploaded_file.name}") | |
if expected_hash: | |
if expected_hash.lower() == file_hash.lower(): | |
st.markdown(""" | |
<div class='status-success'> | |
β Hash cocok! Dokumen terverifikasi. | |
</div> | |
""", unsafe_allow_html=True) | |
else: | |
st.markdown(""" | |
<div class='status-error'> | |
β Hash tidak cocok! Dokumen mungkin telah diubah. | |
</div> | |
""", unsafe_allow_html=True) | |
with col2: | |
st.subheader("Riwayat Verifikasi") | |
history = get_history() | |
if history: | |
for entry in history: | |
with st.expander(f"{entry['filename']}"): | |
st.code(entry['hash'], language='text') | |
st.text(f"Verified: {datetime.fromisoformat(entry['timestamp']).strftime('%Y-%m-%d %H:%M:%S')}") | |
else: | |
st.info("Belum ada riwayat verifikasi") | |
# Features explanation | |
st.markdown("---") | |
feat_col1, feat_col2, feat_col3 = st.columns(3) | |
with feat_col1: | |
st.markdown("### π Real-time Processing") | |
st.markdown("Hasil hash instan saat file diunggah") | |
with feat_col2: | |
st.markdown("### π Multiple Files") | |
st.markdown("Proses beberapa file sekaligus") | |
with feat_col3: | |
st.markdown("### π± QR Code") | |
st.markdown("Share hash dengan mudah via QR") | |
if __name__ == "__main__": | |
main() |