# Implementing an affine cipher

I am trying to create functions for encoding and decoding an affine cipher in Mathematica. I have written these two functions:

EncryptChar[char_, a_, b_] :=
Module[{alphabet, position, shift, mod},
alphabet = Alphabet[];
position = Position[alphabet, char][[1]];
position = position[[1]];
shift = Mod[a*position + b, 26];
Return[alphabet[[shift]]];];

DecryptChar[char_, a_, b_] :=
Module[{alphabet, position, shift, mod},
alphabet = Alphabet[];
position = Position[alphabet, char][[1]];
position = position[[1]];
shift = Mod[a^-1*(position - b), 26];
Return [alphabet[[shift]]];];


And when I try to decode char "p", I get this error:

DecryptChar["p", 3, 5]


During evaluation of In[116]:= Part::pkspec1: The expression 11/3 cannot be used as a part specification. >>

{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"}[[11/3]]


What have I done wrong?

• Isn't the problem that a^-1 is supposed to be the modular inverse of a rather than just 1/a? Yes: replace a^-1 with PowerMod[a, -1, 26] in the definition of DecryptChar. Jan 27, 2016 at 0:24
• @march Woops. Just saw this after I posted. +1 Jan 27, 2016 at 2:00
• In addition to the modulus inverse problem identified by others, shouldn't you check that a is relatively prime to the number of characters in your allowable alphabet (26 in this case)? Jan 27, 2016 at 14:57

You are using the wrong inverse in DecryptChar. You should be using the modular multiplicative inverse but you are using the multiplicative inverse.

DecryptChar[char_, a_, b_] :=
Module[{alphabet, position, shift, mod},
alphabet = Alphabet[];
position = First@Flatten@Position[alphabet, char];
shift = Mod[PowerMod[a, -1, 26] (position - b), 26];
alphabet[[shift]]
]

DecryptChar["p", 3, 5]

(* "u" *)


Hope this helps.

• @m_goldberg Ah, okay. I just zeroed in on the inverse issue. Thanks. Jan 27, 2016 at 3:22
• DecryptChar["p", 3, 5] should not give "u" but "m". The OP's algorithm is incorrect. The correct pairings are u <--> n" and "m <--> p Jan 27, 2016 at 3:24

### Edit

(Corrected error in algorithm)

You can reverse the encryption with Solve, which can handle modular equations.

With[{alphabet = Alphabet[]},
With[{n = Length[alphabet]},
EncryptChar[char_, a_, b_] :=
Module[{position, shift},
position = Position[alphabet, char][[1, 1]] - 1;
shift = Mod[a position + b, n];
alphabet[[shift + 1]]];
DecryptChar[char_, a_, b_] :=
Module[{position, shift},
position = Position[alphabet, char][[1, 1]] - 1;
shift = Solve[a x + b == position, x, Modulus -> n][[1, 1, 2]];
alphabet[[shift + 1]]]]]


Confirm that the code now works:

(DecryptChar[EncryptChar[#, 3, 5], 3, 5] & /@ Alphabet[]) == Alphabet[]


True

Note: I also cleaned up your code a bit.

### Update

I thought about this some more and decided that the problem would be better solved with associations (hash tables). An advantage of this approach is that the coder doesn't to worry about the indexing issues that trouble the OP's code. It is also is concise and efficient.

With[{chars = Alphabet[]},
With[{n = Length[chars]},
With[{
fwdHash = AssociationThread[chars, Range[0, n - 1]],
bkwHash = AssociationThread[Range[0, n - 1], chars]},
encryptChar[char_, a_, b_] := bkwHash @ Mod[a fwdHash[char] + b, n];
decryptChar[char_, a_, b_] :=
bkwHash @ Solve[a x + b == fwdHash[char], x, Modulus -> n][[1, 1, 2]]]]]

(decryptChar[encryptChar[#, 3, 5], 3, 5] & /@ Alphabet[]) == Alphabet[]


True