vincentiusyoshuac commited on
Commit
264d1a9
Β·
verified Β·
1 Parent(s): fb1bc08

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +163 -0
app.py ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import hashlib
3
+ import pandas as pd
4
+ import qrcode
5
+ from io import BytesIO
6
+ from datetime import datetime
7
+ import json
8
+ import base64
9
+
10
+ # Set page config
11
+ st.set_page_config(
12
+ page_title="Document Integrity Checker",
13
+ page_icon="πŸ”",
14
+ layout="wide"
15
+ )
16
+
17
+ # Custom CSS
18
+ st.markdown("""
19
+ <style>
20
+ .stApp {
21
+ max-width: 1200px;
22
+ margin: 0 auto;
23
+ }
24
+ .status-success {
25
+ padding: 1rem;
26
+ border-radius: 4px;
27
+ background-color: #dcfce7;
28
+ color: #166534;
29
+ }
30
+ .status-error {
31
+ padding: 1rem;
32
+ border-radius: 4px;
33
+ background-color: #fee2e2;
34
+ color: #991b1b;
35
+ }
36
+ .hash-display {
37
+ font-family: monospace;
38
+ padding: 1rem;
39
+ background-color: #f8fafc;
40
+ border-radius: 4px;
41
+ }
42
+ </style>
43
+ """, unsafe_allow_html=True)
44
+
45
+ def calculate_hash(file_bytes):
46
+ """Calculate SHA-256 hash of file"""
47
+ sha256_hash = hashlib.sha256()
48
+ sha256_hash.update(file_bytes)
49
+ return sha256_hash.hexdigest()
50
+
51
+ def generate_qr(data):
52
+ """Generate QR code for hash"""
53
+ qr = qrcode.QRCode(version=1, box_size=10, border=5)
54
+ qr.add_data(data)
55
+ qr.make(fit=True)
56
+ img = qr.make_image(fill_color="black", back_color="white")
57
+
58
+ # Convert to bytes
59
+ buffered = BytesIO()
60
+ img.save(buffered, format="PNG")
61
+ return buffered.getvalue()
62
+
63
+ def save_to_history(filename, file_hash):
64
+ """Save verification to history"""
65
+ history = json.loads(st.session_state.get('history', '[]'))
66
+ history.insert(0, {
67
+ 'filename': filename,
68
+ 'hash': file_hash,
69
+ 'timestamp': datetime.now().isoformat()
70
+ })
71
+ # Keep only last 10 entries
72
+ history = history[:10]
73
+ st.session_state['history'] = json.dumps(history)
74
+
75
+ def get_history():
76
+ """Get verification history"""
77
+ try:
78
+ return json.loads(st.session_state.get('history', '[]'))
79
+ except:
80
+ return []
81
+
82
+ def main():
83
+ # Header
84
+ st.title("πŸ” Document Integrity Checker")
85
+ st.markdown("Verifikasi & Lindungi Integritas Dokumen Anda dengan SHA-256")
86
+
87
+ # Main content
88
+ col1, col2 = st.columns([2, 1])
89
+
90
+ with col1:
91
+ st.subheader("Upload Document")
92
+ uploaded_files = st.file_uploader(
93
+ "Drag and drop files here",
94
+ accept_multiple_files=True,
95
+ type=['pdf', 'doc', 'docx', 'txt', 'jpg', 'png']
96
+ )
97
+
98
+ if uploaded_files:
99
+ for uploaded_file in uploaded_files:
100
+ # Calculate hash
101
+ file_bytes = uploaded_file.read()
102
+ file_hash = calculate_hash(file_bytes)
103
+
104
+ # Display hash
105
+ st.markdown(f"**File:** {uploaded_file.name}")
106
+ st.markdown(f"""
107
+ <div class='hash-display'>
108
+ {file_hash}
109
+ </div>
110
+ """, unsafe_allow_html=True)
111
+
112
+ # Generate and display QR
113
+ qr_code = generate_qr(file_hash)
114
+ st.image(qr_code, caption="Scan untuk verifikasi hash")
115
+
116
+ # Save to history
117
+ save_to_history(uploaded_file.name, file_hash)
118
+
119
+ # Verification input
120
+ expected_hash = st.text_input("Masukkan hash untuk verifikasi:", key=f"verify_{uploaded_file.name}")
121
+ if expected_hash:
122
+ if expected_hash.lower() == file_hash.lower():
123
+ st.markdown("""
124
+ <div class='status-success'>
125
+ βœ… Hash cocok! Dokumen terverifikasi.
126
+ </div>
127
+ """, unsafe_allow_html=True)
128
+ else:
129
+ st.markdown("""
130
+ <div class='status-error'>
131
+ ❌ Hash tidak cocok! Dokumen mungkin telah diubah.
132
+ </div>
133
+ """, unsafe_allow_html=True)
134
+
135
+ with col2:
136
+ st.subheader("Riwayat Verifikasi")
137
+ history = get_history()
138
+ if history:
139
+ for entry in history:
140
+ with st.expander(f"{entry['filename']}"):
141
+ st.code(entry['hash'], language='text')
142
+ st.text(f"Verified: {datetime.fromisoformat(entry['timestamp']).strftime('%Y-%m-%d %H:%M:%S')}")
143
+ else:
144
+ st.info("Belum ada riwayat verifikasi")
145
+
146
+ # Features explanation
147
+ st.markdown("---")
148
+ feat_col1, feat_col2, feat_col3 = st.columns(3)
149
+
150
+ with feat_col1:
151
+ st.markdown("### πŸš€ Real-time Processing")
152
+ st.markdown("Hasil hash instan saat file diunggah")
153
+
154
+ with feat_col2:
155
+ st.markdown("### πŸ“ Multiple Files")
156
+ st.markdown("Proses beberapa file sekaligus")
157
+
158
+ with feat_col3:
159
+ st.markdown("### πŸ“± QR Code")
160
+ st.markdown("Share hash dengan mudah via QR")
161
+
162
+ if __name__ == "__main__":
163
+ main()