Monday, April 3, 2017

3X3 Hill Cipher Decoder

I wrote a noob python program to solve a 3X3 Hill Cipher.  Do not use this for your schoolwork or work, I can almost guarantee you will get an F.

I changed the math formulas described here into a python program to decode the 3X3 Hill Cipher.  I do not guarantee that the program functions properly for every cipher-text.  It decoded the cipher-text that I put into it.

Note:  I am not a programmer.  I am not a mathematician.  Yes, there probably is a more efficient way to write this program, but it worked for my purposes. The bits of data after a # sign are comments.  The program doesn't do anything with them.  They are to note things so that I can remember what I was doing.

3X3 Hill Cipher Solver:

HillDecoder.py
#key matrix: 
 #a,b,c
 #d,e,f
 #g,h,i
#Modulus 26 stuff so that I get a number between 0-25, so I can convert it to a letter later.  0=A, 1=B,2=C,...25=Z

a = 00 #A
b = 11 #L
c = 15 #P
d = 07 #H
e = 00 #A
f = 01 #B
g = 04 #E
h = 19 #T
i = 00 #A Not enough letters in key.  This is a filler.

determinant = (a*e*i + b*f*g + c*d*h) - (a*f*h + b*d*i + c*e*g)
#Modulus 26 the determinant to make certain that it is only a number between 0-25
determinantmod26 = determinant % 26

#Trial and Error Multiplicative Inverse:May have to add more if number is large enough.
#Need to find formula to solve this.
for x in range(0,1500):
    multiplicativeinversetest = determinantmod26 * x
    if (multiplicativeinversetest % 26) == 1:
        break;
multiplicativeinverse = x
#adjugate matrix of key matrix 
 #j,k,l
 #m,n,o
 #p,q,r
j = (e*i) - (f*h)
k = (d*i) - (f*g)
l = (d*h) - (e*g)
m = (b*i) - (c*h)
n = (a*i) - (c*g)
o = (a*h) - (b*g)
p = (b*f) - (c*e)
q = (a*f) - (c*d)
r = (a*e) - (b*d)
#switch signs to find co-factor matrix.
k=-k
m=-m
o=-o
q=-q
#reflect matrix to fix adjugate matrix
reflectk = k
k = m
m = reflectk
reflectl = l
l = p
p = reflectl
reflecto = o
o = q
q = reflecto
#modulus 26 adjugate matrix to be certain we only get numbers from 0-25
j = j % 26
k = k % 26
l = l % 26
m = m % 26
n = n % 26
o = o % 26
p = p % 26
q = q % 26
r = r % 26
#inverse key matrix
 #inversej inversek inversel
 #inversem inversen inverseo
 #inversep inverseq inverser
inversej = j * multiplicativeinverse
inversek = k * multiplicativeinverse
inversel = l * multiplicativeinverse
inversem = m * multiplicativeinverse
inversen = n * multiplicativeinverse
inverseo = o * multiplicativeinverse
inversep = p * multiplicativeinverse
inverseq = q * multiplicativeinverse
inverser = r * multiplicativeinverse
#modulus 26 inverse key matrix to get only numbers 0-25
inversej = inversej % 26
inversek = inversek % 26
inversel = inversel % 26
inversem = inversem % 26
inversen = inversen % 26
inverseo = inverseo % 26
inversep = inversep % 26
inverseq = inverseq % 26
inverser = inverser % 26
#cipher text matrix 
 #aa,bb,cc 
 #dd,ee,ff 
 #gg,hh,ii
aa = 18 #S
dd = 24 #Y
gg = 8  #I
bb = 02 #C
ee = 07 #H
hh = 14 #O
cc = 11 #L
ff = 04 #E
ii = 17 #R
#decode cipher matrix using inverse key matrix. (cipher column*corresponding inverse key matrix row.)  Get plain text matrix
#Plain Text Matrix
 #decodeaa decodebb decodecc
 #decodedd decodeee decodeff
 #decodegg decodehh decodeii
decodeaa = (inversej*aa)+(inversek*dd)+(inversel*gg)
decodedd = (inversem*aa)+(inversen*dd)+(inverseo*gg)
decodegg = (inversep*aa)+(inverseq*dd)+(inverser*gg)
decodebb = (inversej*bb)+(inversek*ee)+(inversel*hh)
decodeee = (inversem*bb)+(inversen*ee)+(inverseo*hh)
decodehh = (inversep*bb)+(inverseq*ee)+(inverser*hh)
decodecc = (inversej*cc)+(inversek*ff)+(inversel*ii)
decodeff = (inversem*cc)+(inversen*ff)+(inverseo*ii)
decodeii = (inversep*cc)+(inverseq*ff)+(inverser*ii)
#modulus 26 plain text to get numbers 0-25, which correspond to letters.
decodeaa = decodeaa % 26
decodedd = decodedd % 26
decodegg = decodegg % 26
decodebb = decodebb % 26
decodeee = decodeee % 26
decodehh = decodehh % 26
decodecc = decodecc % 26
decodeff = decodeff % 26
decodeii = decodeii % 26
print("\n")
print(decodeaa) #22-W
print(decodedd) #04-E
print(decodegg) #00-A
print(decodebb) #17-R
print(decodeee) #04-E
print(decodehh) #18-S
print(decodecc) #00-A
print(decodeff) #05-F
print(decodeii) #04-E

5 comments:

  1. Wow.. I am just learning.. But your effort hardly seems noob

    ReplyDelete
  2. This can only decode 9 characters at a time. I need to add a loop to decode more than 9 characters. Also, it doesn't take input from a terminal/file. I'd have to modify it to do so. Seems like people only see what needs to be improved in their own programs. Thanks for your comment.

    ReplyDelete
  3. This comment has been removed by a blog administrator.

    ReplyDelete
  4. Hey, if it works and does the job, it isn't bad code.

    If you're looking for some advice, it would probably have been simpler to implement using numpy matrices. Operations like calculating the determinant and doing the %26 would be a single function call.

    ReplyDelete