SouthParkMe

Hi.

This site tends to hold geeky things.

Automating a Caesar Solver

Automating a Caesar Solver

I wanted to solve the problem not only of solving a caesar shift, but doing it automatically. To do this, I offset the text and count up the number of times each letter appear, and then compare this with English. I assume the best match is the right match, and use this to shift the text back.

Thus, this ciphertext:

DQGQR ZJHQW OHPHQ VDLGG DUWDJ QDQZL
WKRXW VWRSS LQJWR HASOD LQKLV FRQGX
FWWRS RUWKR VDOOI RURQH RQHIR UDOOW
KDWLV RXUPR WWRLV LWQRW DQGBH WVDLG
SRUWK RVKRO GRXWB RXUKD QGDQG VZHDU
FULHG DWKRV DQGDU DPLVD WRQFH RYHUF
RPHEB HADPS OHJUX PEOLQ JWRKL PVHOI
QHYHU WKHOH VVSRU WKRVV WUHWF KHGRX
WKLVK DQGDQ GWKHI RXUIU LHQGV UHSHD
WHGZL WKRQH YRLFH WKHIR UPXOD GLFWD
WHGEB GDUWD JQDQD OOIRU RQHRQ HIRUD
OOWKD WVZHO OQRZO HWXVH YHUBR QHUHW
LUHWR KLVRZ QKRPH VDLGG DUWDJ QDQDV
LIKHK DGGRQ HQRWK LQJEX WFRPP DQGDO
OKLVO LIHDQ GDWWH QWLRQ IRUIU RPWKL
VPRPH QWZHD UHDWI HXGZL WKWKH FDUGL
QDO

Using the automated method, the above text will decode as the following. As the orignal text had no word spacing or punctuation, the same is true here.

ANDNO WGENT LEMEN SAIDD ARTAG NANWI
THOUT STOPP INGTO EXPLA INHIS CONDU
CTTOP ORTHO SALLF ORONE ONEFO RALLT
HATIS OURMO TTOIS ITNOT ANDYE TSAID
PORTH OSHOL DOUTY OURHA NDAND SWEAR
CRIED ATHOS ANDAR AMISA TONCE OVERC
OMEBY EXAMP LEGRU MBLIN GTOHI MSELF
NEVER THELE SSPOR THOSS TRETC HEDOU
THISH ANDAN DTHEF OURFR IENDS REPEA
TEDWI THONE VOICE THEFO RMULA DICTA
TEDBY DARTA GNANA LLFOR ONEON EFORA
LLTHA TSWEL LNOWL ETUSE VERYO NERET
IRETO HISOW NHOME SAIDD ARTAG NANAS
IFHEH ADDON ENOTH INGBU TCOMM ANDAL
LHISL IFEAN DATTE NTION FORFR OMTHI
SMOME NTWEA REATF EUDWI THTHE CARDI
NAL

The spacing was not present in the original text, but we can make out the words:

“And now, gentlemen,” said d’Artagnan, without stopping to explain his conduct to Porthos, “All for one, one for all--that is our motto, is it not?”…..

The code is below.

Recent Cryptography posts

More Cryptography Posts

Here is the code

# this is an automated caesar shift solver
import numpy as np
from math import sqrt

englishdata=[18374,3418,
             4678,11083,
             30430,4396,
             4571,17068,
             13877,223,
             1971,10235,
             5056,15131,
             17579,3353,
             245,12919,
             14424,21889,
             5826,1798,
             6737,225,
             4305,93]

# grab the ciphertext
filetimetable = open("caesarsample.txt","r")
lines=filetimetable.readlines()
filetimetable.close()

# let's make it all one string
working=""
for line in lines:
    for char in line:
        asc=ord(char)
        if (64 < asc < 91) or ( 96 < asc < 123):
            working+=char.upper()

# now let's see what we have:
x=np.arange(26)            
data=np.full(26,0)

for char in working:
    lett=ord(char)-65
    data[lett]+=1

# first let's normalise the english data
tot=0
tot2=0
for i in range(26):
    tot+=data[i]
    tot2+=englishdata[i]
for i in range(26):
    data[i]=data[i]*tot2/tot


# Now, let's find our best candidate for a caesar shift
error=[]
for shift in range(26):
    err=0
    for i in range(26):
        err+=sqrt((data[i]-englishdata[(i+shift)%26])**2)
    error.append(err)

# Finally, we look for the shift that gives us the best match with English
guess=0
best=error[0]

for i in range(26):
        if error[i]<best:
            guess=i
            best=error[i]

# Let's decode with that shift
output=""
for line in lines:
    for char in line:
        asc=ord(char)
        if (64 < asc < 91) or ( 96 < asc < 123):
            if asc<92:
                base=65
            else:
                base=97
            output+=chr((ord(char)-base+guess)%26+base)
            
        else:
            output+=char        
        
print(output)

Links

Arithmetic Tricks - Difference of two

Arithmetic Tricks - Difference of two

Big European Bubble Chamber

Big European Bubble Chamber