cipher-crypter 3.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cipher_crypter/__init__.py +1 -0
- cipher_crypter/cli.py +991 -0
- cipher_crypter-3.0.0.dist-info/METADATA +7 -0
- cipher_crypter-3.0.0.dist-info/RECORD +7 -0
- cipher_crypter-3.0.0.dist-info/WHEEL +5 -0
- cipher_crypter-3.0.0.dist-info/entry_points.txt +2 -0
- cipher_crypter-3.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "3.0.0"
|
cipher_crypter/cli.py
ADDED
|
@@ -0,0 +1,991 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
╔═══════════════════════════════════════════════╗
|
|
4
|
+
║ Cipher Crypter v3.0 — by JosephX ║
|
|
5
|
+
║ Gelişmiş Terminal Şifreleme Aracı ║
|
|
6
|
+
╚═══════════════════════════════════════════════╝
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import time, os, sys, json, random, datetime, hashlib, struct, zlib, hmac
|
|
10
|
+
from dataclasses import dataclass, asdict
|
|
11
|
+
|
|
12
|
+
# ── Renk kodları ─────────────────────────────────────────────────────────────
|
|
13
|
+
class C:
|
|
14
|
+
GREEN = "\033[92m"
|
|
15
|
+
GREEN_DIM = "\033[32m"
|
|
16
|
+
AMBER = "\033[33m"
|
|
17
|
+
RED = "\033[91m"
|
|
18
|
+
CYAN = "\033[96m"
|
|
19
|
+
MAGENTA = "\033[95m"
|
|
20
|
+
WHITE = "\033[97m"
|
|
21
|
+
GRAY = "\033[90m"
|
|
22
|
+
BOLD = "\033[1m"
|
|
23
|
+
RESET = "\033[0m"
|
|
24
|
+
BLINK = "\033[5m"
|
|
25
|
+
|
|
26
|
+
def supports_color():
|
|
27
|
+
return hasattr(sys.stdout, "isatty") and sys.stdout.isatty()
|
|
28
|
+
|
|
29
|
+
if not supports_color():
|
|
30
|
+
for attr in vars(C):
|
|
31
|
+
if not attr.startswith("_"):
|
|
32
|
+
setattr(C, attr, "")
|
|
33
|
+
|
|
34
|
+
# ── Şifreleme seviyeleri ──────────────────────────────────────────────────────
|
|
35
|
+
LEVELS = {
|
|
36
|
+
1: ("EASY", C.GREEN, "░", "Temel sembol kodlama"),
|
|
37
|
+
2: ("MEDIUM", C.CYAN, "▒", "Sembol + XOR katmanı"),
|
|
38
|
+
3: ("HARD", C.AMBER, "▓", "Sembol + XOR + Byte karıştırma"),
|
|
39
|
+
4: ("DEVIL", C.RED, "▲", "HARD + Vigenere + Tuz"),
|
|
40
|
+
5: ("IMPOSSIBLE", C.MAGENTA, "☠", "DEVIL × 3 tur + Padding + Zlib"),
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
LEVEL_COLORS = {1: C.GREEN, 2: C.CYAN, 3: C.AMBER, 4: C.RED, 5: C.MAGENTA}
|
|
44
|
+
|
|
45
|
+
# ── Temel sembol seti (base-13) ───────────────────────────────────────────────
|
|
46
|
+
CHARS = "░▒▓╨╬╥╫╤╞╪╩╧╙"
|
|
47
|
+
BASE = len(CHARS) # 13
|
|
48
|
+
|
|
49
|
+
# ── Desteklenen binary uzantılar ──────────────────────────────────────────────
|
|
50
|
+
BINARY_EXTS = {
|
|
51
|
+
# Video
|
|
52
|
+
".mp4", ".mkv", ".avi", ".mov", ".wmv", ".flv", ".webm", ".m4v",
|
|
53
|
+
# Ses
|
|
54
|
+
".mp3", ".wav", ".flac", ".ogg", ".aac", ".m4a", ".wma",
|
|
55
|
+
# Resim
|
|
56
|
+
".png", ".jpg", ".jpeg", ".gif", ".webp", ".bmp", ".tiff", ".ico", ".svg",
|
|
57
|
+
# Ofis / Doküman
|
|
58
|
+
".pdf", ".docx", ".xlsx", ".pptx", ".odt", ".ods",
|
|
59
|
+
# Arşiv
|
|
60
|
+
".zip", ".rar", ".7z", ".tar", ".gz", ".bz2", ".xz", ".iso",
|
|
61
|
+
# Veri / DB
|
|
62
|
+
".csv", ".json", ".xml", ".db", ".sqlite", ".sql",
|
|
63
|
+
# Uygulama / Sistem
|
|
64
|
+
".exe", ".dll", ".apk", ".bin", ".so", ".dylib",
|
|
65
|
+
# Font / Diğer
|
|
66
|
+
".ttf", ".otf", ".woff", ".woff2",
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
TEXT_EXTS = {".txt", ".md", ".log", ".py", ".js", ".ts", ".html", ".css",
|
|
70
|
+
".sh", ".bat", ".cfg", ".ini", ".yaml", ".yml", ".toml"}
|
|
71
|
+
|
|
72
|
+
def dosya_tipi(path: str) -> str:
|
|
73
|
+
"""'binary', 'text', veya 'unknown' döndür."""
|
|
74
|
+
ext = os.path.splitext(path)[1].lower()
|
|
75
|
+
if ext in BINARY_EXTS: return "binary"
|
|
76
|
+
if ext in TEXT_EXTS: return "text"
|
|
77
|
+
return "unknown" # bilinmeyen → binary olarak işle
|
|
78
|
+
|
|
79
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
80
|
+
# ŞİFRELEME ALGORİTMALARI (bytes → bytes)
|
|
81
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
82
|
+
|
|
83
|
+
def _b13_enc(data: bytes) -> bytes:
|
|
84
|
+
"""Her byte'ı 3 CHARS sembolüyle kodla (hızlı lookup table)."""
|
|
85
|
+
# Lookup table: 256 byte → 3 sembol (UTF-8, her sembol 3 byte = 9 byte/giriş)
|
|
86
|
+
tbl = []
|
|
87
|
+
for b in range(256):
|
|
88
|
+
tbl.append((CHARS[b // (BASE * BASE) % BASE] +
|
|
89
|
+
CHARS[(b // BASE) % BASE] +
|
|
90
|
+
CHARS[b % BASE]).encode("utf-8"))
|
|
91
|
+
out = bytearray()
|
|
92
|
+
for b in data:
|
|
93
|
+
out += tbl[b]
|
|
94
|
+
return bytes(out)
|
|
95
|
+
|
|
96
|
+
def _b13_dec(data: bytes) -> bytes:
|
|
97
|
+
s = data.decode("utf-8")
|
|
98
|
+
if len(s) % 3 != 0:
|
|
99
|
+
raise ValueError("Bozuk veri: uzunluk 3'ün katı değil.")
|
|
100
|
+
# Ters lookup: sembol → değer
|
|
101
|
+
rev = {c: i for i, c in enumerate(CHARS)}
|
|
102
|
+
out = bytearray(len(s) // 3)
|
|
103
|
+
for i in range(0, len(s), 3):
|
|
104
|
+
out[i // 3] = rev[s[i]] * BASE * BASE + rev[s[i+1]] * BASE + rev[s[i+2]]
|
|
105
|
+
return bytes(out)
|
|
106
|
+
|
|
107
|
+
def _xor(data: bytes, key: bytes) -> bytes:
|
|
108
|
+
"""Hızlı XOR: key'i veri uzunluğuna tileleyip bytearray XOR."""
|
|
109
|
+
kl = len(key)
|
|
110
|
+
n = len(data)
|
|
111
|
+
# key'i tam kat + kırıntı olarak tile et
|
|
112
|
+
reps, rem = divmod(n, kl)
|
|
113
|
+
full_key = bytearray(key * reps + key[:rem])
|
|
114
|
+
out = bytearray(n)
|
|
115
|
+
for i in range(n):
|
|
116
|
+
out[i] = data[i] ^ full_key[i]
|
|
117
|
+
return bytes(out)
|
|
118
|
+
|
|
119
|
+
def _make_perm(n: int, seed: int):
|
|
120
|
+
"""Fisher-Yates ile deterministik permütasyon döndür (list[int])."""
|
|
121
|
+
rng = random.Random(seed)
|
|
122
|
+
perm = list(range(n))
|
|
123
|
+
for i in range(n - 1, 0, -1):
|
|
124
|
+
j = rng.randint(0, i)
|
|
125
|
+
perm[i], perm[j] = perm[j], perm[i]
|
|
126
|
+
return perm
|
|
127
|
+
|
|
128
|
+
def _shuffle(data: bytes, seed: int) -> bytes:
|
|
129
|
+
"""Deterministik byte karıştırma.
|
|
130
|
+
perm[i] = j anlamı: orijinal i. byte → çıktıda j. konuma gider.
|
|
131
|
+
out[perm[i]] = data[i]
|
|
132
|
+
"""
|
|
133
|
+
n = len(data)
|
|
134
|
+
perm = _make_perm(n, seed)
|
|
135
|
+
out = bytearray(n)
|
|
136
|
+
for i, p in enumerate(perm):
|
|
137
|
+
out[p] = data[i]
|
|
138
|
+
return bytes(out)
|
|
139
|
+
|
|
140
|
+
def _unshuffle(data: bytes, seed: int) -> bytes:
|
|
141
|
+
"""_shuffle'ın tersi.
|
|
142
|
+
out[i] = data[perm[i]] ← çünkü out[perm[i]]=data[i] idi
|
|
143
|
+
"""
|
|
144
|
+
n = len(data)
|
|
145
|
+
perm = _make_perm(n, seed)
|
|
146
|
+
out = bytearray(n)
|
|
147
|
+
for i, p in enumerate(perm):
|
|
148
|
+
out[i] = data[p]
|
|
149
|
+
return bytes(out)
|
|
150
|
+
|
|
151
|
+
def _vigenere_enc(data: bytes, key: bytes) -> bytes:
|
|
152
|
+
kl = len(key)
|
|
153
|
+
out = bytearray(len(data))
|
|
154
|
+
for i, b in enumerate(data):
|
|
155
|
+
out[i] = (b + key[i % kl]) & 0xFF
|
|
156
|
+
return bytes(out)
|
|
157
|
+
|
|
158
|
+
def _vigenere_dec(data: bytes, key: bytes) -> bytes:
|
|
159
|
+
kl = len(key)
|
|
160
|
+
out = bytearray(len(data))
|
|
161
|
+
for i, b in enumerate(data):
|
|
162
|
+
out[i] = (b - key[i % kl]) & 0xFF
|
|
163
|
+
return bytes(out)
|
|
164
|
+
|
|
165
|
+
def _derive_keys(password: str) -> dict:
|
|
166
|
+
"""Şifreden deterministik anahtarlar türet."""
|
|
167
|
+
h = hashlib.sha256(password.encode("utf-8")).digest()
|
|
168
|
+
return {
|
|
169
|
+
"xor": h[:16],
|
|
170
|
+
"shuffle": struct.unpack("<Q", h[16:24])[0],
|
|
171
|
+
"vigenere": h[8:24],
|
|
172
|
+
"salt": h[4:12],
|
|
173
|
+
"mac": h,
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
# MAC_SIZE: şifreli veriye eklenen imza uzunluğu (byte)
|
|
177
|
+
MAC_SIZE = 16
|
|
178
|
+
|
|
179
|
+
def _mac_sign(data: bytes, key: bytes) -> bytes:
|
|
180
|
+
"""Verinin HMAC-SHA256 imzasının ilk MAC_SIZE byte'ını döndür."""
|
|
181
|
+
return hmac.new(key, data, hashlib.sha256).digest()[:MAC_SIZE]
|
|
182
|
+
|
|
183
|
+
def _mac_verify(data: bytes, key: bytes, tag: bytes) -> bool:
|
|
184
|
+
"""İmzayı doğrula; timing-safe karşılaştırma kullan."""
|
|
185
|
+
expected = _mac_sign(data, key)
|
|
186
|
+
return hmac.compare_digest(expected, tag)
|
|
187
|
+
|
|
188
|
+
# ── Seviyeye göre şifreleme / çözme ──────────────────────────────────────────
|
|
189
|
+
|
|
190
|
+
def _real_progress(label_text: str, fn, *args, color=C.GREEN):
|
|
191
|
+
"""fn(*args) çalıştırır, aynı anda sahte ama gerçekçi progress gösterir."""
|
|
192
|
+
import threading
|
|
193
|
+
result_box = [None]
|
|
194
|
+
err_box = [None]
|
|
195
|
+
done = threading.Event()
|
|
196
|
+
|
|
197
|
+
def worker():
|
|
198
|
+
try:
|
|
199
|
+
result_box[0] = fn(*args)
|
|
200
|
+
except Exception as e:
|
|
201
|
+
err_box[0] = e
|
|
202
|
+
finally:
|
|
203
|
+
done.set()
|
|
204
|
+
|
|
205
|
+
t = threading.Thread(target=worker, daemon=True)
|
|
206
|
+
t.start()
|
|
207
|
+
|
|
208
|
+
width = 44
|
|
209
|
+
filled = 0
|
|
210
|
+
step = 0
|
|
211
|
+
while not done.is_set():
|
|
212
|
+
# Hızlı başla, yavaşla
|
|
213
|
+
inc = max(1, (width - filled) // 8) if filled < width * 0.9 else 0
|
|
214
|
+
filled = min(filled + inc, int(width * 0.97))
|
|
215
|
+
bar = "█" * filled + "░" * (width - filled)
|
|
216
|
+
col = color if filled / width < 0.8 else C.AMBER
|
|
217
|
+
print(f"\r {C.GREEN_DIM}{label_text}{C.RESET} "
|
|
218
|
+
f"[{col}{bar}{C.RESET}] "
|
|
219
|
+
f"{C.WHITE}{int(filled/width*100):3d}%{C.RESET}",
|
|
220
|
+
end="", flush=True)
|
|
221
|
+
done.wait(timeout=0.15)
|
|
222
|
+
step += 1
|
|
223
|
+
|
|
224
|
+
# 100% göster
|
|
225
|
+
bar = "█" * width
|
|
226
|
+
print(f"\r {C.GREEN_DIM}{label_text}{C.RESET} "
|
|
227
|
+
f"[{color}{bar}{C.RESET}] "
|
|
228
|
+
f"{C.WHITE}100%{C.RESET}")
|
|
229
|
+
|
|
230
|
+
if err_box[0]:
|
|
231
|
+
raise err_box[0]
|
|
232
|
+
return result_box[0]
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def enc_level(data: bytes, level: int, password: str,
|
|
236
|
+
show_progress: bool = False) -> bytes:
|
|
237
|
+
k = _derive_keys(password)
|
|
238
|
+
col = LEVEL_COLORS.get(level, C.GREEN)
|
|
239
|
+
|
|
240
|
+
def _run(label, fn, *args):
|
|
241
|
+
if show_progress:
|
|
242
|
+
return _real_progress(label, fn, *args, color=col)
|
|
243
|
+
return fn(*args)
|
|
244
|
+
|
|
245
|
+
if level == 1:
|
|
246
|
+
result = _run(f"[EASY] Kodlanıyor", _b13_enc, data)
|
|
247
|
+
|
|
248
|
+
elif level == 2:
|
|
249
|
+
d = _run(f"[MEDIUM] XOR", _xor, data, k["xor"])
|
|
250
|
+
result = _run(f"[MEDIUM] Kodlanıyor", _b13_enc, d)
|
|
251
|
+
|
|
252
|
+
elif level == 3:
|
|
253
|
+
d = _run(f"[HARD] XOR", _xor, data, k["xor"])
|
|
254
|
+
d = _run(f"[HARD] Karıştırılıyor", _shuffle, d, k["shuffle"])
|
|
255
|
+
result = _run(f"[HARD] Kodlanıyor", _b13_enc, d)
|
|
256
|
+
|
|
257
|
+
elif level == 4:
|
|
258
|
+
d = _run(f"[DEVIL] Vigenere", _vigenere_enc, data, k["vigenere"])
|
|
259
|
+
d = _run(f"[DEVIL] XOR", _xor, d, k["xor"])
|
|
260
|
+
d = _run(f"[DEVIL] Karıştırılıyor", _shuffle, d, k["shuffle"])
|
|
261
|
+
d = k["salt"] + d
|
|
262
|
+
result = _run(f"[DEVIL] Kodlanıyor", _b13_enc, d)
|
|
263
|
+
|
|
264
|
+
elif level == 5:
|
|
265
|
+
d = data
|
|
266
|
+
for turn in range(3):
|
|
267
|
+
tk = _derive_keys(password + str(turn))
|
|
268
|
+
d = _run(f"[IMPOSSIBLE] Tur {turn+1}/3 — Vigenere",
|
|
269
|
+
_vigenere_enc, d, tk["vigenere"])
|
|
270
|
+
d = _run(f"[IMPOSSIBLE] Tur {turn+1}/3 — XOR",
|
|
271
|
+
_xor, d, tk["xor"])
|
|
272
|
+
d = _run(f"[IMPOSSIBLE] Tur {turn+1}/3 — Karıştırma",
|
|
273
|
+
_shuffle, d, tk["shuffle"])
|
|
274
|
+
d = tk["salt"] + d
|
|
275
|
+
pad_len = random.randint(16, 64)
|
|
276
|
+
pad = bytes(random.randint(0, 255) for _ in range(pad_len))
|
|
277
|
+
pad_header = struct.pack("<H", pad_len)
|
|
278
|
+
d = pad_header + pad + d
|
|
279
|
+
if show_progress:
|
|
280
|
+
d = _real_progress("[IMPOSSIBLE] Sıkıştırılıyor",
|
|
281
|
+
zlib.compress, d, 1, color=col)
|
|
282
|
+
else:
|
|
283
|
+
d = zlib.compress(d, level=1)
|
|
284
|
+
result = _run(f"[IMPOSSIBLE] Son kodlama", _b13_enc, d)
|
|
285
|
+
|
|
286
|
+
else:
|
|
287
|
+
raise ValueError(f"Geçersiz seviye: {level}")
|
|
288
|
+
|
|
289
|
+
return _enc_with_mac(result, level, password)
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
def _enc_with_mac(enc_fn_result: bytes, level: int, password: str) -> bytes:
|
|
293
|
+
"""EASY hariç tüm seviyelerde sonuca MAC imzası ekle."""
|
|
294
|
+
if level == 1:
|
|
295
|
+
return enc_fn_result # şifresiz, imza anlamsız
|
|
296
|
+
k = _derive_keys(password)
|
|
297
|
+
tag = _mac_sign(enc_fn_result, k["mac"])
|
|
298
|
+
return tag + enc_fn_result
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
def _dec_verify_mac(data: bytes, level: int, password: str):
|
|
302
|
+
"""MAC'i doğrula ve imzasız veriyi döndür. Hatalı şifrede ValueError fırlatır."""
|
|
303
|
+
if level == 1:
|
|
304
|
+
return data
|
|
305
|
+
if len(data) < MAC_SIZE:
|
|
306
|
+
raise ValueError("Bozuk veri: çok kısa.")
|
|
307
|
+
tag = data[:MAC_SIZE]
|
|
308
|
+
body = data[MAC_SIZE:]
|
|
309
|
+
k = _derive_keys(password)
|
|
310
|
+
if not _mac_verify(body, k["mac"], tag):
|
|
311
|
+
raise ValueError("Hatalı şifre veya bozuk dosya.")
|
|
312
|
+
return body
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
def dec_level(data: bytes, level: int, password: str,
|
|
316
|
+
show_progress: bool = False, has_mac: bool = True) -> bytes:
|
|
317
|
+
# MAC doğrula — yalnızca yeni format (CIPHERX4) dosyalarda
|
|
318
|
+
if has_mac:
|
|
319
|
+
data = _dec_verify_mac(data, level, password)
|
|
320
|
+
|
|
321
|
+
k = _derive_keys(password)
|
|
322
|
+
col = LEVEL_COLORS.get(level, C.GREEN)
|
|
323
|
+
|
|
324
|
+
def _run(label, fn, *args):
|
|
325
|
+
if show_progress:
|
|
326
|
+
return _real_progress(label, fn, *args, color=col)
|
|
327
|
+
return fn(*args)
|
|
328
|
+
|
|
329
|
+
d = _run(f"[{LEVELS[level][0]}] Çözümleniyor", _b13_dec, data)
|
|
330
|
+
|
|
331
|
+
if level == 1:
|
|
332
|
+
return d
|
|
333
|
+
|
|
334
|
+
elif level == 2:
|
|
335
|
+
return _run(f"[MEDIUM] XOR tersle", _xor, d, k["xor"])
|
|
336
|
+
|
|
337
|
+
elif level == 3:
|
|
338
|
+
d = _run(f"[HARD] Sıra geri al", _unshuffle, d, k["shuffle"])
|
|
339
|
+
return _run(f"[HARD] XOR tersle", _xor, d, k["xor"])
|
|
340
|
+
|
|
341
|
+
elif level == 4:
|
|
342
|
+
d = d[len(k["salt"]):]
|
|
343
|
+
d = _run(f"[DEVIL] Sıra geri al", _unshuffle, d, k["shuffle"])
|
|
344
|
+
d = _run(f"[DEVIL] XOR tersle", _xor, d, k["xor"])
|
|
345
|
+
return _run(f"[DEVIL] Vigenere tersle", _vigenere_dec, d, k["vigenere"])
|
|
346
|
+
|
|
347
|
+
elif level == 5:
|
|
348
|
+
if show_progress:
|
|
349
|
+
d = _real_progress("[IMPOSSIBLE] Açılıyor", zlib.decompress, d,
|
|
350
|
+
color=col)
|
|
351
|
+
else:
|
|
352
|
+
d = zlib.decompress(d)
|
|
353
|
+
pad_len = struct.unpack("<H", d[:2])[0]
|
|
354
|
+
d = d[2 + pad_len:]
|
|
355
|
+
for turn in range(2, -1, -1):
|
|
356
|
+
tk = _derive_keys(password + str(turn))
|
|
357
|
+
d = d[len(tk["salt"]):]
|
|
358
|
+
d = _run(f"[IMPOSSIBLE] Tur {turn+1}/3 — Sıra geri al",
|
|
359
|
+
_unshuffle, d, tk["shuffle"])
|
|
360
|
+
d = _run(f"[IMPOSSIBLE] Tur {turn+1}/3 — XOR tersle",
|
|
361
|
+
_xor, d, tk["xor"])
|
|
362
|
+
d = _run(f"[IMPOSSIBLE] Tur {turn+1}/3 — Vigenere tersle",
|
|
363
|
+
_vigenere_dec, d, tk["vigenere"])
|
|
364
|
+
return d
|
|
365
|
+
|
|
366
|
+
raise ValueError(f"Geçersiz seviye: {level}")
|
|
367
|
+
|
|
368
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
369
|
+
# GÖRSEL & YARDIMCI
|
|
370
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
371
|
+
|
|
372
|
+
ASCII_LOGO = f"""\
|
|
373
|
+
{C.GREEN}{C.BOLD}
|
|
374
|
+
██████╗██╗██████╗ ██╗ ██╗███████╗██████╗ ██╗ ██╗
|
|
375
|
+
██╔════╝██║██╔══██╗██║ ██║██╔════╝██╔══██╗ ╚██╗██╔╝
|
|
376
|
+
██║ ██║██████╔╝███████║█████╗ ██████╔╝ ████╗╚███╔╝
|
|
377
|
+
██║ ██║██╔═══╝ ██╔══██║██╔══╝ ██╔══██╗ ╚═══╝██╔██╗
|
|
378
|
+
╚██████╗██║██║ ██║ ██║███████╗██║ ██║ ██╔╝ ██╗
|
|
379
|
+
╚═════╝╚═╝╚═╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═╝
|
|
380
|
+
{C.RESET}{C.GREEN_DIM} Gelişmiş Terminal Şifreleme Aracı v3.0{C.RESET}"""
|
|
381
|
+
|
|
382
|
+
DIVIDER = f"{C.GREEN_DIM}{'═' * 60}{C.RESET}"
|
|
383
|
+
THIN_DIV = f"{C.GREEN_DIM}{'─' * 60}{C.RESET}"
|
|
384
|
+
|
|
385
|
+
def clear():
|
|
386
|
+
os.system("cls" if os.name == "nt" else "clear")
|
|
387
|
+
|
|
388
|
+
def prompt(text="", color=C.GREEN_DIM):
|
|
389
|
+
return input(f"{color}{text}root@cipher:~$ {C.RESET}")
|
|
390
|
+
|
|
391
|
+
def info(msg): print(f" {C.GREEN_DIM}► {msg}{C.RESET}")
|
|
392
|
+
def success(msg): print(f" {C.GREEN}✓ {msg}{C.RESET}")
|
|
393
|
+
def warn(msg): print(f" {C.AMBER}⚠ {msg}{C.RESET}")
|
|
394
|
+
def error(msg): print(f" {C.RED}✗ {msg}{C.RESET}")
|
|
395
|
+
def label(msg): print(f"\n {C.CYAN}{msg}{C.RESET}")
|
|
396
|
+
|
|
397
|
+
def progress_bar(label_text: str, duration: float = 0.6, width: int = 44, color=C.GREEN):
|
|
398
|
+
steps = 35
|
|
399
|
+
for i in range(steps + 1):
|
|
400
|
+
pct = i / steps
|
|
401
|
+
filled = int(width * pct)
|
|
402
|
+
bar = "█" * filled + "░" * (width - filled)
|
|
403
|
+
bar_c = color if pct < 0.8 else C.AMBER
|
|
404
|
+
print(f"\r {C.GREEN_DIM}{label_text}{C.RESET} "
|
|
405
|
+
f"[{bar_c}{bar}{C.RESET}] "
|
|
406
|
+
f"{C.WHITE}{int(pct*100):3d}%{C.RESET}", end="", flush=True)
|
|
407
|
+
time.sleep(duration / steps)
|
|
408
|
+
print()
|
|
409
|
+
|
|
410
|
+
def matrix_rain(rows=3, cols=56, duration=0.6):
|
|
411
|
+
chars = list(CHARS) + list("01░▒▓")
|
|
412
|
+
end_t = time.time() + duration
|
|
413
|
+
while time.time() < end_t:
|
|
414
|
+
for _ in range(rows):
|
|
415
|
+
line = "".join(random.choice(chars) for _ in range(cols))
|
|
416
|
+
print(f" {C.GREEN_DIM}{line}{C.RESET}")
|
|
417
|
+
time.sleep(0.07)
|
|
418
|
+
print(f"\033[{rows}A", end="")
|
|
419
|
+
print(f"\033[{rows}B", end="")
|
|
420
|
+
|
|
421
|
+
def hacker_animasyon(cozulmus: str, sifreli: str):
|
|
422
|
+
print()
|
|
423
|
+
info("Şifre çözme protokolü başlatıldı...")
|
|
424
|
+
time.sleep(0.3)
|
|
425
|
+
print()
|
|
426
|
+
matrix_rain(rows=2, duration=0.5)
|
|
427
|
+
print()
|
|
428
|
+
progress_bar("Analiz ediliyor", duration=0.7)
|
|
429
|
+
print()
|
|
430
|
+
print(f" {C.GREEN_DIM}», ", end="", flush=True)
|
|
431
|
+
for i in range(len(cozulmus) + 1):
|
|
432
|
+
gorunen = cozulmus[:i]
|
|
433
|
+
kalan = sifreli[i*3 : i*3 + min(24, len(sifreli) - i*3)]
|
|
434
|
+
print(f"\r {C.GREEN}» {gorunen}{C.GREEN_DIM}{kalan}{' ' * 6}",
|
|
435
|
+
end="", flush=True)
|
|
436
|
+
time.sleep(0.06)
|
|
437
|
+
print(f"\r {C.GREEN}» {cozulmus}{' ' * 30}{C.RESET}")
|
|
438
|
+
print()
|
|
439
|
+
|
|
440
|
+
def devil_animasyon(level: int):
|
|
441
|
+
"""Seviyeye özel başlangıç animasyonu."""
|
|
442
|
+
name, col, sym, _ = LEVELS[level]
|
|
443
|
+
if level <= 2:
|
|
444
|
+
progress_bar(f"[{name}] Şifreleniyor", duration=0.5, color=col)
|
|
445
|
+
elif level == 3:
|
|
446
|
+
print()
|
|
447
|
+
matrix_rain(rows=2, duration=0.4)
|
|
448
|
+
progress_bar(f"[{name}] Karıştırılıyor", duration=0.7, color=col)
|
|
449
|
+
elif level == 4:
|
|
450
|
+
print()
|
|
451
|
+
matrix_rain(rows=3, duration=0.6)
|
|
452
|
+
progress_bar(f"[{name}] Katmanlar uygulanıyor", duration=1.0, color=col)
|
|
453
|
+
elif level == 5:
|
|
454
|
+
print()
|
|
455
|
+
for _ in range(3):
|
|
456
|
+
matrix_rain(rows=2, duration=0.4)
|
|
457
|
+
time.sleep(0.1)
|
|
458
|
+
progress_bar(f"[{name}] Tur 1/3", duration=0.8, color=col)
|
|
459
|
+
progress_bar(f"[{name}] Tur 2/3", duration=0.8, color=col)
|
|
460
|
+
progress_bar(f"[{name}] Tur 3/3", duration=0.8, color=col)
|
|
461
|
+
progress_bar(f"[{name}] Finalize", duration=0.5, color=col)
|
|
462
|
+
|
|
463
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
464
|
+
# DOSYA OKUMA / YAZMA
|
|
465
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
466
|
+
|
|
467
|
+
def oku_dosya(path: str) -> bytes:
|
|
468
|
+
"""Her türlü dosyayı bytes olarak oku."""
|
|
469
|
+
with open(path, "rb") as f:
|
|
470
|
+
return f.read()
|
|
471
|
+
|
|
472
|
+
def yaz_dosya(path: str, data: bytes):
|
|
473
|
+
with open(path, "wb") as f:
|
|
474
|
+
f.write(data)
|
|
475
|
+
|
|
476
|
+
def temizle_yol(p: str) -> str:
|
|
477
|
+
return p.strip().strip('"').strip("'")
|
|
478
|
+
|
|
479
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
480
|
+
# .CIPHERX DOSYA FORMATI
|
|
481
|
+
# CIPHERX3 (eski): CIPHERX3:<seviye>:<ext>:<tip>\n + şifreli veri (MAC yok)
|
|
482
|
+
# CIPHERX4 (yeni): CIPHERX4:<seviye>:<ext>:<tip>\n + şifreli veri (MAC tag dahil)
|
|
483
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
484
|
+
|
|
485
|
+
MAGIC_V3 = "CIPHERX3" # geriye uyumluluk (MAC yok)
|
|
486
|
+
MAGIC_V4 = "CIPHERX4" # yeni format (MAC tag gömülü)
|
|
487
|
+
MAGIC = MAGIC_V4 # yeni dosyalar için
|
|
488
|
+
|
|
489
|
+
def build_header(level: int, ext: str, tip: str) -> bytes:
|
|
490
|
+
return f"{MAGIC}:{level}:{ext}:{tip}\n".encode("utf-8")
|
|
491
|
+
|
|
492
|
+
def parse_header(raw: bytes) -> tuple:
|
|
493
|
+
"""(level, ext, tip, rest_data, has_mac) döndür."""
|
|
494
|
+
try:
|
|
495
|
+
nl = raw.index(b"\n")
|
|
496
|
+
header = raw[:nl].decode("utf-8")
|
|
497
|
+
rest = raw[nl+1:]
|
|
498
|
+
parts = header.split(":")
|
|
499
|
+
if len(parts) < 4:
|
|
500
|
+
raise ValueError()
|
|
501
|
+
magic = parts[0]
|
|
502
|
+
if magic == MAGIC_V4:
|
|
503
|
+
has_mac = True
|
|
504
|
+
elif magic == MAGIC_V3:
|
|
505
|
+
has_mac = False
|
|
506
|
+
else:
|
|
507
|
+
raise ValueError()
|
|
508
|
+
return int(parts[1]), parts[2], parts[3], rest, has_mac
|
|
509
|
+
except Exception:
|
|
510
|
+
raise ValueError("Geçersiz veya eski format CIPHERX dosyası.")
|
|
511
|
+
|
|
512
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
513
|
+
# ŞİFRE SEÇİM MENÜSÜ
|
|
514
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
515
|
+
|
|
516
|
+
def sifre_sec_ekran() -> tuple[int, str]:
|
|
517
|
+
"""(level, password) döndür. İptal için (0, '') """
|
|
518
|
+
print()
|
|
519
|
+
print(f" {THIN_DIV}")
|
|
520
|
+
print(f" {C.BOLD}{C.WHITE} Şifreleme Seviyesi Seç:{C.RESET}")
|
|
521
|
+
print(f" {THIN_DIV}")
|
|
522
|
+
for lvl, (name, col, sym, desc) in LEVELS.items():
|
|
523
|
+
print(f" {col}[{lvl}] {sym} {name:<12}{C.RESET} {C.GRAY}{desc}{C.RESET}")
|
|
524
|
+
print(f" {C.GRAY}[0] İptal{C.RESET}")
|
|
525
|
+
print(f" {THIN_DIV}")
|
|
526
|
+
print()
|
|
527
|
+
|
|
528
|
+
while True:
|
|
529
|
+
secim = prompt("Seviye (1-5): ").strip()
|
|
530
|
+
if secim == "0": return 0, ""
|
|
531
|
+
if secim.isdigit() and 1 <= int(secim) <= 5:
|
|
532
|
+
level = int(secim)
|
|
533
|
+
break
|
|
534
|
+
warn("Geçersiz seviye.")
|
|
535
|
+
|
|
536
|
+
name, col, sym, _ = LEVELS[level]
|
|
537
|
+
print()
|
|
538
|
+
|
|
539
|
+
if level == 1:
|
|
540
|
+
info(f"{col}{name}{C.RESET} — şifre gerektirmez, Enter'a bas.")
|
|
541
|
+
password = ""
|
|
542
|
+
else:
|
|
543
|
+
import getpass
|
|
544
|
+
print(f" {col}{sym} {name} seviyesi için şifre belirle:{C.RESET}")
|
|
545
|
+
while True:
|
|
546
|
+
try:
|
|
547
|
+
pw1 = getpass.getpass(f" {C.GREEN_DIM}Şifre: {C.RESET}")
|
|
548
|
+
pw2 = getpass.getpass(f" {C.GREEN_DIM}Tekrar: {C.RESET}")
|
|
549
|
+
except Exception:
|
|
550
|
+
# getpass desteklenmiyorsa
|
|
551
|
+
pw1 = prompt("Şifre: ")
|
|
552
|
+
pw2 = pw1
|
|
553
|
+
if pw1 == pw2 and pw1:
|
|
554
|
+
password = pw1
|
|
555
|
+
break
|
|
556
|
+
warn("Şifreler eşleşmedi veya boş, tekrar dene.")
|
|
557
|
+
|
|
558
|
+
print()
|
|
559
|
+
return level, password
|
|
560
|
+
|
|
561
|
+
def sifre_gir_ekran(level: int) -> str:
|
|
562
|
+
"""Çözme için şifre gir."""
|
|
563
|
+
name, col, sym, _ = LEVELS[level]
|
|
564
|
+
if level == 1:
|
|
565
|
+
return ""
|
|
566
|
+
import getpass
|
|
567
|
+
print(f" {col}{sym} {name} — Şifreyi gir:{C.RESET}")
|
|
568
|
+
try:
|
|
569
|
+
return getpass.getpass(f" {C.GREEN_DIM}Şifre: {C.RESET}")
|
|
570
|
+
except Exception:
|
|
571
|
+
return prompt("Şifre: ")
|
|
572
|
+
|
|
573
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
574
|
+
# İSTATİSTİK & GEÇMİŞ
|
|
575
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
576
|
+
|
|
577
|
+
@dataclass
|
|
578
|
+
class GirdiCikti:
|
|
579
|
+
tip: str
|
|
580
|
+
girdi: str
|
|
581
|
+
cikti: str
|
|
582
|
+
zaman: str
|
|
583
|
+
seviye: str = "?"
|
|
584
|
+
|
|
585
|
+
HISTORY_FILE = os.path.join(os.path.expanduser("~"), ".cipher_crypter_history.json")
|
|
586
|
+
stats = {"enc": 0, "dec": 0, "bytes": 0}
|
|
587
|
+
history: list[GirdiCikti] = []
|
|
588
|
+
|
|
589
|
+
def load_history():
|
|
590
|
+
global history
|
|
591
|
+
if os.path.exists(HISTORY_FILE):
|
|
592
|
+
try:
|
|
593
|
+
with open(HISTORY_FILE, "r", encoding="utf-8") as f:
|
|
594
|
+
raw = json.load(f)
|
|
595
|
+
history = []
|
|
596
|
+
for item in raw:
|
|
597
|
+
if isinstance(item, dict):
|
|
598
|
+
item.setdefault("seviye", "?")
|
|
599
|
+
history.append(GirdiCikti(**item))
|
|
600
|
+
except Exception:
|
|
601
|
+
history = []
|
|
602
|
+
|
|
603
|
+
def save_history():
|
|
604
|
+
try:
|
|
605
|
+
with open(HISTORY_FILE, "w", encoding="utf-8") as f:
|
|
606
|
+
json.dump([asdict(h) for h in history[-100:]], f,
|
|
607
|
+
ensure_ascii=False, indent=2)
|
|
608
|
+
except Exception:
|
|
609
|
+
pass
|
|
610
|
+
|
|
611
|
+
def add_to_history(tip, girdi, cikti, seviye="?"):
|
|
612
|
+
history.append(GirdiCikti(
|
|
613
|
+
tip=tip, girdi=girdi, cikti=cikti,
|
|
614
|
+
zaman=datetime.datetime.now().strftime("%d.%m.%Y %H:%M:%S"),
|
|
615
|
+
seviye=seviye,
|
|
616
|
+
))
|
|
617
|
+
save_history()
|
|
618
|
+
|
|
619
|
+
def show_stats():
|
|
620
|
+
print(f"\n {THIN_DIV}")
|
|
621
|
+
print(f" {C.GREEN_DIM} ŞİFRELENEN {C.GREEN}{stats['enc']:>5}{C.RESET}"
|
|
622
|
+
f" {C.GREEN_DIM}ÇÖZÜLEN {C.GREEN}{stats['dec']:>5}{C.RESET}"
|
|
623
|
+
f" {C.GREEN_DIM}TOPLAM {C.GREEN}{stats['bytes']/1024:>8.1f} KB{C.RESET}")
|
|
624
|
+
print(f" {THIN_DIV}\n")
|
|
625
|
+
|
|
626
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
627
|
+
# MENÜ & HEADER
|
|
628
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
629
|
+
|
|
630
|
+
def draw_header():
|
|
631
|
+
clear()
|
|
632
|
+
print(ASCII_LOGO)
|
|
633
|
+
print(DIVIDER)
|
|
634
|
+
show_stats()
|
|
635
|
+
|
|
636
|
+
def show_menu():
|
|
637
|
+
print(f" {C.GREEN}[1]{C.RESET} {C.WHITE}Şifrele{C.RESET} "
|
|
638
|
+
f"{C.GRAY}(metin · txt · mp4 · mp3 · zip · docx · bilinmeyen...){C.RESET}")
|
|
639
|
+
print(f" {C.GREEN}[2]{C.RESET} {C.WHITE}Şifre Çöz{C.RESET} "
|
|
640
|
+
f"{C.GRAY}(.cipherx dosyası veya şifreli metin){C.RESET}")
|
|
641
|
+
print(f" {C.GREEN}[3]{C.RESET} {C.WHITE}Hızlı Test{C.RESET} "
|
|
642
|
+
f"{C.GRAY}(Şifrele → Çöz → Doğrula){C.RESET}")
|
|
643
|
+
print(f" {C.GREEN}[4]{C.RESET} {C.WHITE}Geçmiş{C.RESET}")
|
|
644
|
+
print(f" {C.GREEN}[5]{C.RESET} {C.WHITE}Hakkında{C.RESET}")
|
|
645
|
+
print(f" {C.RED}[0]{C.RESET} {C.GRAY}Çıkış{C.RESET}")
|
|
646
|
+
print()
|
|
647
|
+
|
|
648
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
649
|
+
# EKRANLAR
|
|
650
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
651
|
+
|
|
652
|
+
def ekran_sifrele():
|
|
653
|
+
draw_header()
|
|
654
|
+
label("ŞİFRELEME MODU")
|
|
655
|
+
print(THIN_DIV)
|
|
656
|
+
girdi = prompt("Dosya yolu veya şifrelenecek metin: ")
|
|
657
|
+
if not girdi:
|
|
658
|
+
warn("Boş girdi."); time.sleep(1); return
|
|
659
|
+
|
|
660
|
+
girdi = temizle_yol(girdi)
|
|
661
|
+
|
|
662
|
+
# Dosya mı, metin mi?
|
|
663
|
+
if os.path.exists(girdi):
|
|
664
|
+
tip = dosya_tipi(girdi)
|
|
665
|
+
try:
|
|
666
|
+
data = oku_dosya(girdi)
|
|
667
|
+
except Exception as exc:
|
|
668
|
+
error(f"Dosya okunamadı: {exc}"); time.sleep(2); return
|
|
669
|
+
orijinal_ext = os.path.splitext(girdi)[1].lower() or ".bin"
|
|
670
|
+
kaynak_etiket = f"{girdi} ({len(data)/1024:.1f} KB, {tip})"
|
|
671
|
+
is_file = True
|
|
672
|
+
else:
|
|
673
|
+
# Metin girişi
|
|
674
|
+
data = girdi.encode("utf-8")
|
|
675
|
+
orijinal_ext = ".txt"
|
|
676
|
+
tip = "text"
|
|
677
|
+
kaynak_etiket = f"metin ({len(data)} byte)"
|
|
678
|
+
is_file = False
|
|
679
|
+
|
|
680
|
+
info(f"Kaynak: {kaynak_etiket}")
|
|
681
|
+
print()
|
|
682
|
+
|
|
683
|
+
# Seviye & şifre seç
|
|
684
|
+
level, password = sifre_sec_ekran()
|
|
685
|
+
if level == 0: return
|
|
686
|
+
|
|
687
|
+
name, col, sym, _ = LEVELS[level]
|
|
688
|
+
print()
|
|
689
|
+
# devil_animasyon artık enc_level içinde gerçek progress olarak gösteriliyor
|
|
690
|
+
|
|
691
|
+
try:
|
|
692
|
+
sifreli_data = enc_level(data, level, password, show_progress=True)
|
|
693
|
+
except Exception as exc:
|
|
694
|
+
error(f"Şifreleme hatası: {exc}"); time.sleep(2); return
|
|
695
|
+
|
|
696
|
+
header = build_header(level, orijinal_ext, tip)
|
|
697
|
+
son_veri = header + sifreli_data
|
|
698
|
+
|
|
699
|
+
# Çıktı yolu
|
|
700
|
+
if is_file:
|
|
701
|
+
default_out = os.path.splitext(girdi)[0] + ".cipherx"
|
|
702
|
+
else:
|
|
703
|
+
default_out = os.path.join(os.getcwd(), "output.cipherx")
|
|
704
|
+
|
|
705
|
+
out_yol = prompt(f"Çıktı dosyası [Enter = {default_out}]: ").strip().strip('"').strip("'")
|
|
706
|
+
if not out_yol: out_yol = default_out
|
|
707
|
+
if not out_yol.lower().endswith(".cipherx"):
|
|
708
|
+
out_yol += ".cipherx"
|
|
709
|
+
|
|
710
|
+
try:
|
|
711
|
+
yaz_dosya(out_yol, son_veri)
|
|
712
|
+
except Exception as exc:
|
|
713
|
+
error(f"Kaydedilemedi: {exc}"); time.sleep(2); return
|
|
714
|
+
|
|
715
|
+
print()
|
|
716
|
+
success(f"Şifreleme tamamlandı!")
|
|
717
|
+
info(f"Seviye : {col}{sym} {name}{C.RESET}")
|
|
718
|
+
info(f"Çıktı : {out_yol}")
|
|
719
|
+
info(f"Boyut : {len(data)/1024:.1f} KB → {len(son_veri)/1024:.1f} KB")
|
|
720
|
+
print()
|
|
721
|
+
stats["enc"] += 1
|
|
722
|
+
stats["bytes"] += len(data)
|
|
723
|
+
add_to_history("ENC", girdi[:60], out_yol, name)
|
|
724
|
+
input(f" {C.GRAY}[ Devam için Enter ]{C.RESET} ")
|
|
725
|
+
|
|
726
|
+
|
|
727
|
+
def ekran_coz():
|
|
728
|
+
draw_header()
|
|
729
|
+
label("ŞİFRE ÇÖZME MODU")
|
|
730
|
+
print(THIN_DIV)
|
|
731
|
+
girdi = prompt("Şifreli metin veya .cipherx dosya yolu: ")
|
|
732
|
+
if not girdi:
|
|
733
|
+
warn("Boş girdi."); time.sleep(1); return
|
|
734
|
+
|
|
735
|
+
girdi = temizle_yol(girdi)
|
|
736
|
+
|
|
737
|
+
# .cipherx dosyası mı?
|
|
738
|
+
if girdi.lower().endswith(".cipherx") or (os.path.exists(girdi) and _is_cipherx(girdi)):
|
|
739
|
+
if not os.path.exists(girdi):
|
|
740
|
+
error(f"Dosya bulunamadı: {girdi}"); time.sleep(2); return
|
|
741
|
+
_coz_dosya(girdi)
|
|
742
|
+
return
|
|
743
|
+
|
|
744
|
+
# Eski format metin mi? (EASY seviyesi, şifresiz)
|
|
745
|
+
_coz_metin(girdi)
|
|
746
|
+
|
|
747
|
+
|
|
748
|
+
def _is_cipherx(path: str) -> bool:
|
|
749
|
+
try:
|
|
750
|
+
with open(path, "rb") as f:
|
|
751
|
+
start = f.read(len(MAGIC))
|
|
752
|
+
return start == MAGIC.encode("utf-8")
|
|
753
|
+
except Exception:
|
|
754
|
+
return False
|
|
755
|
+
|
|
756
|
+
|
|
757
|
+
def _coz_dosya(dosya_yolu: str):
|
|
758
|
+
try:
|
|
759
|
+
raw = oku_dosya(dosya_yolu)
|
|
760
|
+
except Exception as exc:
|
|
761
|
+
error(f"Dosya okunamadı: {exc}"); time.sleep(2); return
|
|
762
|
+
|
|
763
|
+
try:
|
|
764
|
+
level, orijinal_ext, tip, sifreli_data, has_mac = parse_header(raw)
|
|
765
|
+
except ValueError as exc:
|
|
766
|
+
error(str(exc)); time.sleep(2); return
|
|
767
|
+
|
|
768
|
+
name, col, sym, _ = LEVELS.get(level, (str(level), C.WHITE, "?", ""))
|
|
769
|
+
info(f"Seviye algılandı: {col}{sym} {name}{C.RESET}")
|
|
770
|
+
info(f"Orijinal uzantı : {orijinal_ext} | Tip: {tip}")
|
|
771
|
+
print()
|
|
772
|
+
|
|
773
|
+
password = sifre_gir_ekran(level)
|
|
774
|
+
print()
|
|
775
|
+
|
|
776
|
+
try:
|
|
777
|
+
orijinal_data = dec_level(sifreli_data, level, password, show_progress=True, has_mac=has_mac)
|
|
778
|
+
except ValueError as exc:
|
|
779
|
+
msg = str(exc)
|
|
780
|
+
if "Hatalı şifre" in msg:
|
|
781
|
+
print()
|
|
782
|
+
error("╔══════════════════════════════════════════╗")
|
|
783
|
+
error("║ ✗ HATALI ŞİFRE — Çözme iptal edildi ║")
|
|
784
|
+
error("╚══════════════════════════════════════════╝")
|
|
785
|
+
else:
|
|
786
|
+
error(f"Çözme hatası: {exc}")
|
|
787
|
+
time.sleep(2); return
|
|
788
|
+
except Exception as exc:
|
|
789
|
+
error(f"Çözme hatası: {exc}"); time.sleep(2); return
|
|
790
|
+
|
|
791
|
+
base = os.path.splitext(dosya_yolu)[0]
|
|
792
|
+
default_out = base + ".recovered" + orijinal_ext
|
|
793
|
+
out_yol = prompt(f"Çıktı dosyası [Enter = {default_out}]: ").strip().strip('"').strip("'")
|
|
794
|
+
if not out_yol: out_yol = default_out
|
|
795
|
+
|
|
796
|
+
try:
|
|
797
|
+
yaz_dosya(out_yol, orijinal_data)
|
|
798
|
+
except Exception as exc:
|
|
799
|
+
error(f"Kaydedilemedi: {exc}"); time.sleep(2); return
|
|
800
|
+
|
|
801
|
+
print()
|
|
802
|
+
success(f"Çözme tamamlandı!")
|
|
803
|
+
info(f"Seviye : {col}{sym} {name}{C.RESET}")
|
|
804
|
+
info(f"Çıktı : {out_yol}")
|
|
805
|
+
info(f"Boyut : {len(orijinal_data)/1024:.1f} KB kurtarıldı")
|
|
806
|
+
|
|
807
|
+
# Metin ise ekrana da göster
|
|
808
|
+
if tip == "text" and len(orijinal_data) < 2000:
|
|
809
|
+
try:
|
|
810
|
+
metin_str = orijinal_data.decode("utf-8")
|
|
811
|
+
print()
|
|
812
|
+
hacker_animasyon(metin_str, sifreli_data.decode("utf-8", errors="replace"))
|
|
813
|
+
except Exception:
|
|
814
|
+
pass
|
|
815
|
+
print()
|
|
816
|
+
stats["dec"] += 1
|
|
817
|
+
stats["bytes"] += len(orijinal_data)
|
|
818
|
+
add_to_history("DEC", dosya_yolu, out_yol, name)
|
|
819
|
+
input(f" {C.GRAY}[ Devam için Enter ]{C.RESET} ")
|
|
820
|
+
|
|
821
|
+
|
|
822
|
+
def _coz_metin(sifreli_str: str):
|
|
823
|
+
"""Eski tarz düz metin şifresi çöz (seviye 1 varsayılan)."""
|
|
824
|
+
info("Düz metin modu (EASY seviyesi varsayılıyor)...")
|
|
825
|
+
print()
|
|
826
|
+
progress_bar("Analiz ediliyor", duration=0.5)
|
|
827
|
+
try:
|
|
828
|
+
# Önce EASY dene
|
|
829
|
+
data = sifreli_str.encode("utf-8")
|
|
830
|
+
orijinal = dec_level(data, 1, "")
|
|
831
|
+
metin = orijinal.decode("utf-8")
|
|
832
|
+
except Exception:
|
|
833
|
+
error("Geçersiz şifreli veri! Semboller tanınamadı veya format hatalı.")
|
|
834
|
+
info("Not: Şifre korumalı dosyalar için .cipherx formatını kullanın.")
|
|
835
|
+
time.sleep(2); return
|
|
836
|
+
|
|
837
|
+
hacker_animasyon(metin, sifreli_str)
|
|
838
|
+
print()
|
|
839
|
+
out_yol = prompt("Çıktı dosyası [boş = ekrana yaz]: ").strip().strip('"').strip("'")
|
|
840
|
+
if out_yol:
|
|
841
|
+
try:
|
|
842
|
+
yaz_dosya(out_yol, metin.encode("utf-8"))
|
|
843
|
+
success(f"Kaydedildi: {out_yol}")
|
|
844
|
+
except Exception as exc:
|
|
845
|
+
error(f"Kaydedilemedi: {exc}")
|
|
846
|
+
else:
|
|
847
|
+
success(f"Çözülen metin ({len(metin)} karakter):")
|
|
848
|
+
print(f" {C.WHITE}{metin}{C.RESET}")
|
|
849
|
+
print()
|
|
850
|
+
stats["dec"] += 1
|
|
851
|
+
stats["bytes"] += len(metin)
|
|
852
|
+
add_to_history("DEC", sifreli_str[:40], metin[:40], "EASY")
|
|
853
|
+
input(f" {C.GRAY}[ Devam için Enter ]{C.RESET} ")
|
|
854
|
+
|
|
855
|
+
|
|
856
|
+
def ekran_hizli_test():
|
|
857
|
+
draw_header()
|
|
858
|
+
label("HIZLI TEST MODU")
|
|
859
|
+
print(THIN_DIV)
|
|
860
|
+
|
|
861
|
+
metin = prompt("Test Metni: ")
|
|
862
|
+
if not metin:
|
|
863
|
+
warn("Boş metin."); time.sleep(1); return
|
|
864
|
+
|
|
865
|
+
level, password = sifre_sec_ekran()
|
|
866
|
+
if level == 0: return
|
|
867
|
+
|
|
868
|
+
name, col, sym, _ = LEVELS[level]
|
|
869
|
+
data = metin.encode("utf-8")
|
|
870
|
+
print()
|
|
871
|
+
|
|
872
|
+
info(f"Adım 1/3 — {col}{sym} {name}{C.RESET} şifreleniyor...")
|
|
873
|
+
progress_bar("", duration=0.5, color=col)
|
|
874
|
+
try:
|
|
875
|
+
enc = enc_level(data, level, password)
|
|
876
|
+
except Exception as exc:
|
|
877
|
+
error(f"Şifreleme hatası: {exc}"); time.sleep(2); return
|
|
878
|
+
preview = enc[:60].decode("utf-8", errors="replace")
|
|
879
|
+
success(f"Şifreli: {preview}{'…' if len(enc) > 60 else ''}")
|
|
880
|
+
print()
|
|
881
|
+
|
|
882
|
+
info("Adım 2/3 — Çözülüyor...")
|
|
883
|
+
progress_bar("", duration=0.5, color=col)
|
|
884
|
+
try:
|
|
885
|
+
dec_data = dec_level(enc, level, password)
|
|
886
|
+
dec = dec_data.decode("utf-8")
|
|
887
|
+
except Exception as exc:
|
|
888
|
+
error(f"Çözme hatası: {exc}"); time.sleep(2); return
|
|
889
|
+
success(f"Çözülen: {dec[:60]}{'…' if len(dec) > 60 else ''}")
|
|
890
|
+
print()
|
|
891
|
+
|
|
892
|
+
info("Adım 3/3 — Doğrulanıyor...")
|
|
893
|
+
progress_bar("", duration=0.3)
|
|
894
|
+
ok = dec == metin
|
|
895
|
+
print()
|
|
896
|
+
if ok:
|
|
897
|
+
success(f"TEST BAŞARILI ✓ — {col}{sym} {name}{C.RESET} tutarlı!")
|
|
898
|
+
else:
|
|
899
|
+
error("TEST BAŞARISIZ ✗ — Tutarsızlık tespit edildi!")
|
|
900
|
+
print()
|
|
901
|
+
info(f"Orijinal boyut : {len(data)} byte")
|
|
902
|
+
info(f"Şifreli boyut : {len(enc)} byte ({len(enc)/len(data):.1f}x)")
|
|
903
|
+
print()
|
|
904
|
+
input(f" {C.GRAY}[ Devam için Enter ]{C.RESET} ")
|
|
905
|
+
|
|
906
|
+
|
|
907
|
+
def ekran_gecmis():
|
|
908
|
+
draw_header()
|
|
909
|
+
label("GEÇMİŞ")
|
|
910
|
+
print(THIN_DIV)
|
|
911
|
+
if not history:
|
|
912
|
+
info("Geçmiş boş.")
|
|
913
|
+
input(f"\n {C.GRAY}[ Devam için Enter ]{C.RESET} ")
|
|
914
|
+
return
|
|
915
|
+
gorunen = history[-15:][::-1]
|
|
916
|
+
for i, h in enumerate(gorunen, 1):
|
|
917
|
+
tip_str = f"{C.GREEN}ŞİF{C.RESET}" if "ENC" in h.tip else f"{C.AMBER}ÇÖZ{C.RESET}"
|
|
918
|
+
sev_col = next((LEVEL_COLORS[k] for k,v in LEVELS.items() if v[0]==h.seviye), C.GRAY)
|
|
919
|
+
plain_k = h.girdi[:30] + ("…" if len(h.girdi) > 30 else "")
|
|
920
|
+
print(f" {C.GRAY}{i:>2}.{C.RESET} [{tip_str}] "
|
|
921
|
+
f"{sev_col}[{h.seviye:<10}]{C.RESET} "
|
|
922
|
+
f"{C.WHITE}{plain_k:<33}{C.RESET} "
|
|
923
|
+
f"{C.GRAY}{h.zaman}{C.RESET}")
|
|
924
|
+
print()
|
|
925
|
+
input(f" {C.GRAY}[ Devam için Enter ]{C.RESET} ")
|
|
926
|
+
|
|
927
|
+
|
|
928
|
+
def ekran_hakkinda():
|
|
929
|
+
draw_header()
|
|
930
|
+
label("HAKKINDA")
|
|
931
|
+
print(THIN_DIV)
|
|
932
|
+
lines = [
|
|
933
|
+
("Cipher Crypter v3.0", C.WHITE),
|
|
934
|
+
("Gelişmiş Terminal Şifreleme Aracı", C.GREEN_DIM),
|
|
935
|
+
("", ""),
|
|
936
|
+
("SEVİYELER:", C.CYAN),
|
|
937
|
+
(f" {C.GREEN}[1] ░ EASY {C.GRAY}Temel sembol kodlama (şifresiz)", ""),
|
|
938
|
+
(f" {C.CYAN}[2] ▒ MEDIUM {C.GRAY}Sembol + XOR katmanı", ""),
|
|
939
|
+
(f" {C.AMBER}[3] ▓ HARD {C.GRAY}Sembol + XOR + Byte karıştırma", ""),
|
|
940
|
+
(f" {C.RED}[4] ▲ DEVIL {C.GRAY}HARD + Vigenere + Tuz", ""),
|
|
941
|
+
(f" {C.MAGENTA}[5] ☠ IMPOSSIBLE{C.GRAY} DEVIL × 3 tur + Padding + Zlib", ""),
|
|
942
|
+
("", ""),
|
|
943
|
+
("DOSYA DESTEĞİ:", C.CYAN),
|
|
944
|
+
(" mp4 · mp3 · wav · flac · ogg (ses/video)", C.GRAY),
|
|
945
|
+
(" png · jpg · gif · webp · svg (resim)", C.GRAY),
|
|
946
|
+
(" zip · rar · 7z · tar · gz · iso (arşiv)", C.GRAY),
|
|
947
|
+
(" pdf · docx · xlsx · pptx (ofis)", C.GRAY),
|
|
948
|
+
(" csv · json · xml · db · sqlite (veri)", C.GRAY),
|
|
949
|
+
(" exe · apk · bin · dll (uygulama)", C.GRAY),
|
|
950
|
+
(" + bilinmeyen uzantılar otomatik binary olarak şifrelenir", C.GREEN_DIM),
|
|
951
|
+
("", ""),
|
|
952
|
+
("FORMAT:", C.CYAN),
|
|
953
|
+
(" .cipherx — Tüm metadata header'da saklanır.", C.GRAY),
|
|
954
|
+
(" Çözerken seviye & uzantı otomatik algılanır.", C.GRAY),
|
|
955
|
+
("", ""),
|
|
956
|
+
("Geliştirici:", C.GREEN_DIM),
|
|
957
|
+
("JosephX", C.GREEN),
|
|
958
|
+
]
|
|
959
|
+
for text, color in lines:
|
|
960
|
+
if text == "":
|
|
961
|
+
print()
|
|
962
|
+
else:
|
|
963
|
+
print(f" {color}{text}{C.RESET}")
|
|
964
|
+
print()
|
|
965
|
+
input(f" {C.GRAY}[ Devam için Enter ]{C.RESET} ")
|
|
966
|
+
|
|
967
|
+
|
|
968
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
969
|
+
# ANA DÖNGÜ
|
|
970
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
971
|
+
|
|
972
|
+
def main():
|
|
973
|
+
load_history()
|
|
974
|
+
while True:
|
|
975
|
+
draw_header()
|
|
976
|
+
show_menu()
|
|
977
|
+
secim = prompt().strip()
|
|
978
|
+
if secim == "1": ekran_sifrele()
|
|
979
|
+
elif secim == "2": ekran_coz()
|
|
980
|
+
elif secim == "3": ekran_hizli_test()
|
|
981
|
+
elif secim == "4": ekran_gecmis()
|
|
982
|
+
elif secim == "5": ekran_hakkinda()
|
|
983
|
+
elif secim == "0":
|
|
984
|
+
clear()
|
|
985
|
+
print(f"\n {C.GREEN}İyi günler!{C.RESET}\n")
|
|
986
|
+
sys.exit(0)
|
|
987
|
+
else:
|
|
988
|
+
warn("Geçersiz seçim."); time.sleep(0.8)
|
|
989
|
+
|
|
990
|
+
if __name__ == "__main__":
|
|
991
|
+
main()
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
cipher_crypter/__init__.py,sha256=pKtrXU-VRct109vbaZQ0DAvZOVVUyX9Ty63Xl1nsAy4,23
|
|
2
|
+
cipher_crypter/cli.py,sha256=a8wXqeQccJC-h-MzC72AnXGZF6x4BhNzHOsl8sEt9WE,39988
|
|
3
|
+
cipher_crypter-3.0.0.dist-info/METADATA,sha256=BapyotD77tFHaOvHG_1x0GfZrjcbPJOhsWlL6DzPz5I,152
|
|
4
|
+
cipher_crypter-3.0.0.dist-info/WHEEL,sha256=51RkbunBAw4BWsgaQWTpPhg4Diwp3c9P5iaLk67Hdtg,92
|
|
5
|
+
cipher_crypter-3.0.0.dist-info/entry_points.txt,sha256=h5hpTQcTnbPjGiFRybQYVBj09OXYCASbrxQOH_dZxFA,59
|
|
6
|
+
cipher_crypter-3.0.0.dist-info/top_level.txt,sha256=pQNLRrMcL7J1mSOU6UV_RpVzqS7TgeMZySAKK3xTKeY,15
|
|
7
|
+
cipher_crypter-3.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
cipher_crypter
|