Affine is a monoalphabetic substitution cipher. Each letter in the alphabet is mapped to a number, then encrypted/decrypted using a math formula, and finally converted back to a letter.
✅ Perfect Decoding
✅ Uppercase letters (A-Z
)
✅ Lowercase letters (a-z
)
❌ Numbers (0-9
)
❌ Symbols (!@#$
)
❌ Emojis (😍🤬👩🏾💻
)
Numbers, Symbols, and Emojis
Numbers, symbols, and emoji are outputted as-is by this cipher.
What is “Perfect Decoding”?
Perfect Decoding is when the decoded text exactly matches the text that was encoded.
((coprime * letterPosition) + shift) mod 26
(modInverseOfCoprime * (letterPosition - shift)) mod 26
Based on the current settings for Affine:
coprime = 3
shift = 6
modInverseOfCoprime = 9
((3 * letterPosition) + 6) mod 26
(9 * (letterPosition - 6)) mod 26
Hello World!
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
0123456789
!@#$
✨🦄✨
Bsnnw Uwfnp!
GJMPSVYBEHKNQTWZCFILORUXAD
gjmpsvybehknqtwzcfiloruxad
0123456789
!@#$
✨🦄✨
Hello World!
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
0123456789
!@#$
✨🦄✨
letterPosition
is the index of the lettercoprime
and shift
are two variables you pick!modInverseOfCoprime
is the modular multiplicative inverse of coprime
You’ll see a lot of references to 26
, it’s not a magic number, just the
number of letters in the English alphabet.
letterPosition
Index of the letter in the English alphabet (0-indexed). For example,
A=0, B=1, C=2, and so on until Z=25.
coprime
Must be a number where the only positive integer that divides it and 26 is 1. With that limitation the only valid values are: 1, 3, 5, 7, 9, 11, 15, 17, 19, 21, 23, 25
shift
Any integer, positive or negative
modInverseOfCoprime
The modular multiplicative inverse of the coprime
. To be honest, I don’t fully understand the formula.
But, after extensive searching, I got a rough understanding that we need to find a number where the formula below would be correct.
(coprime * x) % 26 = 1
The value of x
is the modular multiplicative inverse of coprime
. The following javascript function, stolen converted from the examples here calculates the value for x
.
function _modInverse (coprime) {
let mod = utils.TOTAL_ALPHA
let inverse = 1
let y = 0
while (coprime > 1) {
let origMod = mod
let origY = y
let quotient = Math.floor(coprime / mod)
mod = coprime % mod
coprime = origMod
y = inverse - quotient * y
inverse = origY
if (inverse < 0) {
inverse += utils.TOTAL_ALPHA
}
}
return inverse
}
mod 26
Both formulas for encoding and decoding have mod 26
which performs the modulo (%) operation on the output.
This is a safe-keeping action to guarantee the character is one of the 26 letters in the alphabet. Javascript doesn’t have proper support for mod so this formula is used:
export function mod (a, b) {
return ((a % b) + b) % b
}