Skip to content

Instantly share code, notes, and snippets.

@Ap0dexMe0
Created July 18, 2025 21:44
Show Gist options
  • Select an option

  • Save Ap0dexMe0/d7f68a4f406eec5dce2d47f81a2019a5 to your computer and use it in GitHub Desktop.

Select an option

Save Ap0dexMe0/d7f68a4f406eec5dce2d47f81a2019a5 to your computer and use it in GitHub Desktop.
Cryptography, Encoding & Obfuscation Analyzer
import base64
import binascii
import re
import urllib.parse
import codecs
import math
import html
import quopri
import string
class DETECTION:
def __init__(self):
self.findings = []
def analyze(self, data: str) -> list:
self.findings = []
# ==== ENCODING ====
self._check_base64(data)
self._check_base32(data)
self._check_base16(data)
self._check_base58(data)
self._check_base85(data)
self._check_ascii85(data)
self._check_hex(data)
self._check_url_encoding(data)
self._check_html_entities(data)
self._check_quoted_printable(data)
self._check_uuencode(data)
self._check_morse_code(data)
# ==== ENCRYPTION (heuristic) ====
self._check_entropy(data)
self._check_openssl(data)
self._check_pem_blocks(data)
self._check_jwt(data)
self._check_fernet(data)
self._check_zip(data)
self._check_pdf(data)
self._check_ms_office(data)
# ==== OBFUSCATION ====
self._check_rot13(data)
self._check_rot47(data)
self._check_xor(data)
self._check_reversed(data)
self._check_eval_patterns(data)
self._check_double_base64(data)
self._check_unicode_escape(data)
self._check_jsfuck(data)
self._check_emoji_obfuscation(data)
# ==== HASH TYPE ====
self._check_hash_type(data)
return list(set(self.findings))
# === ENCODING DETECTION ===
def _check_base64(self, data):
try:
base64.b64decode(data, validate=True)
self.findings.append("Base64")
except: pass
def _check_base32(self, data):
try:
base64.b32decode(data)
self.findings.append("Base32")
except: pass
def _check_base16(self, data):
try:
base64.b16decode(data.upper())
self.findings.append("Base16")
except: pass
def _check_base58(self, data):
if all(c in '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' for c in data):
self.findings.append("Base58")
def _check_base85(self, data):
try:
base64.b85decode(data)
self.findings.append("Base85")
except: pass
def _check_ascii85(self, data):
try:
base64.a85decode(data)
self.findings.append("ASCII85")
except: pass
def _check_hex(self, data):
try:
bytes.fromhex(data)
self.findings.append("Hexadecimal")
except: pass
def _check_url_encoding(self, data):
if urllib.parse.unquote(data) != data:
self.findings.append("URL Encoded")
def _check_html_entities(self, data):
if html.unescape(data) != data:
self.findings.append("HTML Entities")
def _check_quoted_printable(self, data):
try:
if quopri.decodestring(data.encode()).decode(errors='ignore') != data:
self.findings.append("Quoted-Printable")
except: pass
def _check_uuencode(self, data):
if re.match(r'begin [0-7]{3} .+', data):
self.findings.append("UUEncode")
def _check_morse_code(self, data):
if re.fullmatch(r'[\.\-\s]+', data.strip()):
self.findings.append("Morse Code")
# === ENCRYPTION DETECTION (Heuristics) ===
def _check_entropy(self, data):
if len(data) < 16:
return
entropy = -sum((p := data.count(c) / len(data)) * math.log2(p) for c in set(data))
if entropy > 4.5:
self.findings.append("High Entropy (Possibly Encrypted)")
def _check_openssl(self, data):
if data.startswith("Salted__"):
self.findings.append("OpenSSL AES Encrypted")
def _check_pem_blocks(self, data):
if re.search(r'-----BEGIN (RSA|PGP|ENCRYPTED|CERTIFICATE)', data):
self.findings.append("PEM Encrypted Block")
def _check_jwt(self, data):
parts = data.split(".")
if len(parts) == 3:
try:
base64.urlsafe_b64decode(parts[1] + '==')
self.findings.append("JWT Token")
except: pass
def _check_fernet(self, data):
try:
decoded = base64.urlsafe_b64decode(data + '==')
if len(decoded) == 128:
self.findings.append("Fernet Token")
except: pass
def _check_zip(self, data):
if data.startswith("PK\x03\x04"):
self.findings.append("Encrypted ZIP Archive")
def _check_pdf(self, data):
if "%PDF" in data and "/Encrypt" in data:
self.findings.append("Encrypted PDF")
def _check_ms_office(self, data):
if data.startswith("\xd0\xcf\x11\xe0"):
self.findings.append("MS Office Compound File (Possibly Encrypted)")
# === OBFUSCATION DETECTION ===
def _check_rot13(self, data):
try:
if codecs.decode(data, 'rot_13') != data:
self.findings.append("ROT13")
except: pass
def _check_rot47(self, data):
decoded = ''.join(
chr(33 + ((ord(c) - 33 + 47) % 94)) if 33 <= ord(c) <= 126 else c for c in data
)
if decoded != data:
self.findings.append("ROT47")
def _check_xor(self, data):
try:
raw = bytes(data, 'utf-8')
for key in range(1, 256):
xor_result = bytes([b ^ key for b in raw])
ascii_ratio = sum([32 <= c < 127 for c in xor_result]) / len(xor_result)
if ascii_ratio > 0.9:
self.findings.append("XOR Obfuscation (Heuristic)")
break
except: pass
def _check_reversed(self, data):
if data[::-1].isprintable():
self.findings.append("Reversed String")
def _check_eval_patterns(self, data):
if "eval(" in data or "String.fromCharCode" in data:
self.findings.append("JavaScript Obfuscation (eval/charCode)")
def _check_double_base64(self, data):
try:
first = base64.b64decode(data)
second = base64.b64decode(first)
if second:
self.findings.append("Double Base64")
except:
pass
def _check_unicode_escape(self, data):
if "\\u" in data:
self.findings.append("Unicode Escaped")
def _check_jsfuck(self, data):
if all(c in '[]()+! ' for c in data.strip()) and len(data) > 10:
self.findings.append("JSFuck (Obfuscated JS)")
def _check_emoji_obfuscation(self, data):
emoji_pattern = re.compile("["
"\U0001F600-\U0001F64F" # emoticons
"\U0001F300-\U0001F5FF" # symbols & pictographs
"\U0001F680-\U0001F6FF" # transport & map
"\U0001F1E0-\U0001F1FF" # flags
"]+", flags=re.UNICODE)
if emoji_pattern.search(data):
self.findings.append("Emoji Obfuscation")
def _check_hash_type(self, data):
hash_patterns = {
r'^[a-f0-9]{32}$': 'MD5',
r'^[A-F0-9]{32}$': 'LM Hash',
r'^[a-f0-9]{40}$': 'SHA1',
r'^[a-f0-9]{56}$': 'SHA224',
r'^[a-f0-9]{64}$': 'SHA256 / BLAKE2s',
r'^[a-f0-9]{96}$': 'SHA384',
r'^[a-f0-9]{128}$': 'SHA512 / BLAKE2b',
r'^[A-F0-9]{16}$': 'Oracle 10g Hash',
r'^[0-9a-f]{8}$': 'CRC32',
r'^[0-9]{10}$': 'CRC32 (decimal)',
r'^\$2[aby]\$.{56}$': 'bcrypt',
r'^\$s0\$.*': 'scrypt',
r'^\$pbkdf2-.+\$': 'PBKDF2',
r'^\$argon2(id|i|d)\$.*': 'Argon2',
r'^\$P\$.*': 'Wordpress MD5',
r'^\$H\$.*': 'Drupal MD5',
r'^\$S\$.*': 'Drupal SHA512',
r'^\*[A-F0-9]{40}$': 'MySQL 5+ (SHA1)',
r'^[A-F0-9]{16}$': 'MySQL Pre-4.1',
}
for pattern, name in hash_patterns.items():
if re.fullmatch(pattern, data):
self.findings.append(f"Hash Type: {name}")
break
if __name__ == "__main__":
detector = DETECTION()
samples = [
"5f4dcc3b5aa765d61d8327deb882cf99", # MD5
"900150983cd24fb0d6963f7d28e17f72", # MD5
"5baa61e4c9b93f3f0682250b6cf8331b", # SHA1-like
"2c1743a391305fbf367df8e4f069f9f9", # NTLM
"$2a$12$EXRkfkdmXn2gzds2SSitu.", # bcrypt
"$argon2id$v=19$m=65536,t=2,p=1$...", # Argon2
"U29tZVRleHQ=", # Base64
"68656c6c6f", # Hex
"Uryyb Jbeyq!", # ROT13
"eval(String.fromCharCode(65))", # JS Obfuscation
"PK\x03\x04", # ZIP Header
"Salted__\x9a\xbc...", # OpenSSL
"%68%65%6C%6C%6F", # URL
"[+![]]", # JSFuck
"πŸ˜ŠπŸ”πŸš€", # Emoji Obfuscation
]
for s in samples:
print(f"Input: {s}")
print(f"Detected: {detector.analyze(s)}\n")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment