I want to decrypt the following classical Cipher-text without knowing key:
Cq ligss’v vcjandd ujw, wuqjwgausjkq cv ulxucdd zrj mhuouahj lbh nuvl upgoqlm rx mhfmllcyw cqxiueuwaiq kbdjyg ghoahh, xlre jhjmrfuo vuws nr fuwaiqsf vwwuwnv. Sm fqvhj nkjydlm ewwrey lfwuwuvahjds vgjkamwawdlyg, ulbhnryldhbb whdtfhk mdxy fggpmhluuwaiq, hlrlyflcqy yywlblblfa ijip ghoahh tuqccqy nushvswwaiqk uqv ghvcfsf uwwrjxv li sjcysnh uiqnyukuwaiqk. Cw hlrncgwm wzy eswntiqw zrj xdlu lfnhyllls dfx fghiaxhfnlsflls, hfmxjcqy nksn rffb ahwwhgwx uwwlhchfnv uuq swfwmv kyqkcwaph vuws uqv nksn ll lheulfm xfwkshjwx gmllfa wjuqkglkmlgh. Fjsslijjuszs qgn rffb kuiwaxslgk cqvcyaxxsfv’ hllnufq vxl uoki xfxhjjlfm jdiesf fggpwlfw, mhuouw wregxfcfsnlghv, shg fuwaiqsf vwwxjcwq, gdccqy cw ahgamswhvsvow cq s qrjfg lbdl lhdchk iq vcjandd nummw.
So far I have used different online-tools unsucessfully.
I inspired from this source using Pythonic code to reach:
import argparse
class CaesarAlgorithm:
def encrypt(self, message, key, alphabet):
# start with empty ciphertext
ciphertext = ""
# iterate through each character in message
for old_character in message:
new_character = ""
# if character is in alphabet -> append to ciphertext
if(old_character in alphabet):
index = alphabet.index(old_character)
new_index = (index + key) % len(alphabet)
new_character = alphabet[new_index]
# Note: characters not defined in the alphabet are ignored
# add new character to ciphertext
ciphertext = ciphertext + new_character
# return ciphertext to calling function
return ciphertext
def decrypt(self, message, key, alphabet):
# decrypting is like encrypting but with negative key
plaintext = self.encrypt(message, 0 - key, alphabet)
# return plaintext to calling function
return plaintext
# parse the arguments (args) given via the command line
parser = argparse.ArgumentParser()
parser.add_argument("-e", "--encrypt", dest="encrypt_or_decrypt", action="store_true")
parser.add_argument("-d", "--decrypt", dest="encrypt_or_decrypt", action="store_false")
parser.add_argument("-m", "--message", help="message for encrypt / decrypt", type=str)
parser.add_argument("-k", "--key", help="key for encrypt / decrypt", type=int)
parser.add_argument("-a", "--alphabet", help="defined alphabet", type=str)
ciphertext="Cq ligss’v vcjandd ujw, wuqjwgausjkq cv ulxucdd zrj mhuouahj lbh nuvl upgoqlm rx mhfmllcyw cqxiueuwaiq kbdjyg ghoahh, xlre jhjmrfuo vuws nr fuwaiqsf vwwuwnv. Sm fqvhj nkjydlm ewwrey lfwuwuvahjds vgjkamwawdlyg, ulbhnryldhbb whdtfhk mdxy fggpmhluuwaiq, hlrlyflcqy yywlblblfa ijip ghoahh tuqccqy nushvswwaiqk uqv ghvcfsf uwwrjxv li sjcysnh uiqnyukuwaiqk. Cw hlrncgwm wzy eswntiqw zrj xdlu lfnhyllls dfx fghiaxhfnlsflls, hfmxjcqy nksn rffb ahwwhgwx uwwlhchfnv uuq swfwmv kyqkcwaph vuws uqv nksn ll lheulfm xfwkshjwx gmllfa wjuqkglkmlgh. Fjsslijjuszs qgn rffb kuiwaxslgk cqvcyaxxsfv’ hllnufq vxl uoki xfxhjjlfm jdiesf fggpwlfw, mhuouw wregxfcfsnlghv, shg fuwaiqsf vwwxjcwq, gdccqy cw ahgamswhvsvow cq s qrjfg lbdl lhdchk iq vcjandd nummw."
# Simulate command-line arguments
# Replace with your desired values
args = parser.parse_args(["-d", "-m", ciphertext, "-k", "3", "-a", "abcdefghijklmnopqrstuvwxyz"])
# create caesar instance
caesar = CaesarAlgorithm()
# if --encrypt -> call encrypt function
if(args.encrypt_or_decrypt == True):
print(caesar.encrypt(args.message, args.key, args.alphabet))
# if --decrypt -> call decrypt function
else:
print(caesar.decrypt(args.message, args.key, args.alphabet))
So far, I could not achieve Plain Text and find the identified key Even I have tried to use the following online tools and find the key mannually but I could not yet:
Your cipher text is not encoded with a Caesar Cipher, it is encoded with a Vigenere Cipher with the key uds
.
You can write a Vigenere Cipher:
class VigenereCipher:
@staticmethod
def _key_iter(key):
while True:
for ch in key:
yield ch
@staticmethod
def _lookup_table(key, alphabet):
if any(ch not in alphabet for ch in key):
raise ValueError("Key should be in the alphabet")
return {
ch: alphabet[alphabet.index(ch):] + alphabet[:alphabet.index(ch)]
for ch in key
}
@staticmethod
def encode(message, key, alphabet="abcdefghijklmnopqrstuvwxyz"):
lookup = VigenereCipher._lookup_table(key, alphabet)
key_iter = VigenereCipher._key_iter(key)
return "".join(
lookup[next(key_iter)][alphabet.index(ch)]
if ch in alphabet else ch
for ch in message
)
@staticmethod
def decode(message, key, alphabet="abcdefghijklmnopqrstuvwxyz"):
lookup = VigenereCipher._lookup_table(key, alphabet)
key_iter = VigenereCipher._key_iter(key)
return "".join(
alphabet[lookup[next(key_iter)].index(ch)]
if ch in alphabet else ch
for ch in message
)
Then if you know the key (and alphabet), you can decode the string:
ciphertext="Cq ligss’v vcjandd ujw, wuqjwgausjkq cv ulxucdd zrj mhuouahj"
print(VigenereCipher.decode(ciphertext.lower(), "uds"))
Which outputs:
in today’s digital age, cryptography is crucial for securing
If you want to find an unknown key then you will have to:
For example, if you know the key is length 3 and has no repeated characters then you can generate potential solutions using:
from itertools import permutations
common_two_letter_words = ("as", "to", "be", "in", "by", "is", "it", "at", "of", "or", "on", "an", "us", "if", "my", "do", "no", "he", "up", "so", "am", "me", "go", "hi")
def has_vowel(word):
return any(vowel in word for vowel in "aeiouy")
for key in permutations(alphabet, 3):
output = VigenereCipher.decode(ciphertext.lower(), key)
if (
output[:2] in common_two_letter_words
and output[9] == "s"
and all(has_vowel(word) for word in output.split(" "))
and output[37:39] in common_two_letter_words
):
print("".join(key), output)
Which looks to see if the input decodes the two-letter words to common words and that the character after the apostrophe is an s
and that each word contains at least one vowel and outputs:
cdo an xgdeq’s hagmlap sgi, urchtsyrehhc as gjugaap xov kegmrmfg
cds an tgdaq’s dagilal sge, uryhtoyrahhy as cjucaal xor kecmrifg
cdy an ngduq’s xagclaf sgy, urshtiyruhhs as wjuwaaf xol kewmrcfg
udc in jodqy’s tigytab agu, croptegrqpho is srusiab foh sesuryng
ude in hodoy’s rigwtaz ags, crmptcgrophm is qruqiaz fof sequrwng
udg in fodmy’s pigutax agq, crkptagrmphk is oruoiax fod seourung
udi in dodky’s nigstav ago, criptygrkphi is mrumiav fob semursng
udk in bodiy’s ligqtat agm, crgptwgriphg is krukiat foz sekurqng
udm in zodgy’s jigotar agk, creptugrgphe is iruiiar fox seiurong
udo in xodey’s higmtap agi, crcptsgrephc is grugiap fov segurmng
udq in vodcy’s figktan agg, craptqgrcpha is erueian fot seeurkng
uds in today’s digital age, cryptography is crucial for securing
udw in podwy’s zigetah aga, cruptkgrwphu is yruyiah fon seyureng
udy in noduy’s xigctaf agy, crsptigruphs is wruwiaf fol sewurcng
The correct solution is in there and the other solutions are gibberish. With more analysis (and a dictionary of more and longer words) you can narrow down the solution to the correct key. That is left as an exercise for the reader.