picoctf/crypto/substitution2/solve.py

145 lines
2.7 KiB
Python
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env nix-shell
#!nix-shell -i python -p python3
# NOTE: the colors are used to keep track of which letters have been
# already substituted, and which are still unknown.
def green(s):
return f"\033[42m{s}\033[0m"
def red(s):
return f"\033[41m{s}\033[0m"
def substitute(cipher_text, substitution_map):
for letter in cipher_text:
if letter.lower() in substitution_map:
if letter.isupper():
x = substitution_map[letter.lower()].upper()
else:
x = substitution_map[letter]
print(green(x), end="")
else:
print(red(letter), end="")
with open('message.txt', 'r') as file:
enc = file.read()
# Here, I will be slowly substituting the letters in the ciphertext
# based on what I believe the words to be. I have commented out the
# invocations of substitute, and commented the newly found letters
# after each invocation.
# Starting off, "sxzqZNV{...}" looks like "picoCTF{...}"
substitution_map = {
'0': '0',
'1': '1',
'2': '2',
'3': '3',
'4': '4',
'5': '5',
'6': '6',
'7': '7',
'8': '8',
'9': '9',
'_': '_',
'{': '{',
'}': '}',
's': 'p',
'x': 'i',
'z': 'c',
'q': 'o',
'n': 't',
'v': 'f',
}
# substitute(enc, substitution_map)
# Using frequency analysis (https://www.dcode.fr/frequency-analysis), we find that:
# F 175× 13.87%
# N 125× 9.9%
# X 103× 8.16%
# Q 102× 8.08%
# L 98× 7.77%
# E 83× 6.58%
# T 68× 5.39%
# Z 63× 4.99%
# Y 61× 4.83%
# A 56× 4.44%
# P 46× 3.65%
# W 42× 3.33%
# V 39× 3.09%
# G 35× 2.77%
# B 34× 2.69%
# S 28× 2.22%
# R 24× 1.9%
# U 20× 1.58%
# H 19× 1.51%
# K 16× 1.27%
# M 9× 0.71%
# C 9× 0.71%
# O 5× 0.4%
# I 2× 0.16%
# Based on this, and the frequency of letters in the english alphabet, we can guess for 'e'
substitution_map['f'] = 'e' # 13.87% ~= 12.7%
# 'petitiol' -> 'petition'
substitution_map['l'] = 'n'
# 'incpwbinr' -> 'including'
# 'effectiue' -> 'effective'
substitution_map['p'] = 'l'
substitution_map['w'] = 'u'
substitution_map['b'] = 'd'
substitution_map['r'] = 'g'
# 'encountey' -> 'encounter'
substitution_map['y'] = 'r'
# 'eecurith' -> 'security'
substitution_map['e'] = 's'
substitution_map['h'] = 'y'
# 'effectiuely' -> 'effectively'
substitution_map['u'] = 'v'
# 'cogputer' -> 'computer'
substitution_map['g'] = 'm'
# 'catllenge' -> 'challenge'
substitution_map['a'] = 'h'
substitution_map['t'] = 'a'
# 'thinc' -> 'think'
substitution_map['c'] = 'k'
# 'valuakle' -> 'valuable'
substitution_map['k'] = 'b'
# 'thereeoists' -> 'there exists'
substitution_map['o'] = 'x'
# 'homever' -> 'however'
substitution_map['m'] = 'w'
# 'techniiue' -b 'technique'
substitution_map['i'] = 'q'
substitute(enc, substitution_map)