# Is this decryption function idiomatic?

This is my first non-trivial Mathematica notebook, which I wrote for a cryptology homework. It encrypts/decrypts strings using an affine cipher. Is the code readable/idiomatic? How could it be improved? (I'm using version 10, so I don't have the ModularInverse function).

toNum[c_] := LetterNumber[c] - 1

toChar[n_] := Alphabet[][[n + 1]]

encryptAffine[m_, b_] := StringJoin[
toChar[
Mod[m toNum[#] + b, 26]
] & /@ Characters[#]
] &

decryptAffine[m_, b_] := StringJoin[
toChar[
Mod[
PowerMod[m, -1, 26]*(toNum[#] - b),
26
]
] & /@ Characters[#]
] &

decryptAffine[3, 7][encryptAffine[3, 7]["helloworld"]]

(* "helloworld" *)


## 1 Answer

Expressive enough for my taste. But a bit shorter and much faster (by 3 orders of magnitude) would be to use ToCharacterCode and FromCharacterCode as follows:

decryptAffine2[m_, b_] := FromCharacterCode[
Mod[PowerMod[m, -1, 26] (ToCharacterCode[#] - (97 + b)), 26] + 97
] &;

f = decryptAffine[3, 7];
g = decryptAffine2[3, 7];
s = StringJoin[RandomChoice[Alphabet[], 10000]];
r1 = f[s]; // AbsoluteTiming // First
r2 = g[s]; // AbsoluteTiming // First
r1 == r2


1.28523

0.000329

True

ToCharacterCode has the advantage that it transforms a string into a packed array. Moreover the arithmetic operations are vectorized so that they can applied componentwise to arrays. This often provides enormous speedup compared to using Map.

• Thanks for the tip, hadn't heard of that function! Commented Aug 19, 2018 at 22:40