Int('x')120
In which I use Integer arithmetic on Characters to implement a simple Caesar cipher.
August 27, 2025
Julia’s Char type was a new concept for me, as discussed in my previous post. To wrap my head around this, I implement a Caesar cipher to encrypt and decrypt simple messages.
As you probably know, this is not a secure encryption method at all. According to Wikipedia: “…the Caesar cipher is easily broken and in modern practice offers essentially no communications security.”
However, I found this a neat little exercise to work with.
In Julia, Int('x') returns the decimal Unicode index for a character. For lower case “x” this would be 120:
With this decimal representation of letters available, it is possible to do some mathematical operations on a Char, like addition and subtraction:
Now, if we convert the derived new value back to a letter using Char() we have successfully shifted the letter, just like in a Caesar cipher, AKA “shift cipher”:
'z': ASCII/Unicode U+007A (category Ll: Letter, lowercase)
Mathematically, the cyclical shifting around the alphabet can be represented by modular arithmetic. This is described in detail in the Wikipedia article. In short: Encrypting a character \(x\) shifting by \(n\) positions can be described as:
\[ E_n(x)=(x+n)\;mod\;26 \]
The latin alphabet1 only starts at Unicode index 65 (capital letters) and index 97 (lower case letters). To use modular arithmetic, we need to first subtract this number from the character we’re working on in the following functions. After “modulo-shifting”, we add this number back and get the encrypted letter.
convert_lowercase (generic function with 1 method)
As you can see above, we only encrypt letters, not punctuation, to keep it simple.
convert_uppercase (generic function with 1 method)
function caesar_encrypt(msg::String, n_offset)
# reduce redundant rotations around the alphabet for offsets > 26
n_offset = n_offset % 26
# a negative offset can be mapped to a corresponding positive offset
if n_offset < 0
n_offset = 26 + n_offset
end
String([if islowercase(x) convert_lowercase(x, n_offset) else convert_uppercase(x, n_offset) end for x in collect(msg)])
endcaesar_encrypt (generic function with 1 method)
Decrypting simply means shifting back each letter by the same offset:
\[ E_n(x)=(x-n)\;mod\;26 \]
Accordingly, the decryption function is the encryption with the negative offset:
Now the fun part: Let’s play a bit with the cipher:
Soothsayer:
Beware the ides of March.
The Life and Death of Julius Caesar – William Shakespeare*2
"Gjbfwj ymj nijx tk Rfwhm."
To boil down three functions to two, we’ll put the control flow between upper and lower case letters into the rotate function. Using multiple dispatch, we define one version of the cipher function for when we’re working on a Char type and another for when we’re working with a String.
function rotate(n_offset::Int, msg::Char)
if isletter(msg)
if isuppercase(msg)
Char(((Int(msg) - Int('A')) + n_offset ) % 26 + Int('A'))
else
Char(((Int(msg) - Int('a')) + n_offset ) % 26 + Int('a'))
end
else
return msg
end
end
function rotate(n_offset::Int, msg::String)
n_offset = n_offset % 26
if n_offset < 0
n_offset = 26 + n_offset
end
String([rotate(n_offset, x) for x in collect(msg)])
endrotate (generic function with 2 methods)
Let’s check this version with a longer quote3:
Vjwpfgt cpf nkijvpkpi. Gpvgt ECGUCT, kp jku pkijv-iqyp
ECGUCT
Pqt jgcxgp pqt gctvj jcxg dggp cv rgceg vq-pkijv:
Vjtkeg jcvj Ecnrwtpkc kp jgt unggr etkgf qwv,
'Jgnr, jq! vjga owtfgt Ecguct!' Yjq'u ykvjkp?
Julia offers a very interesting way to work with strings, called non-standard string literals.
Based on the abovementioned Julia manual and this comment on stackoverflow, we can implement this as follows:
With this, we can “encrypt” strings like so:
This returns the same result, as seen in Section 4. With this macro we can adjust the flag very easily:
As a final teaser, I’ll leave you an encrypted message without telling you the offset. If you “crack” this Caesar cipher using brute force4, feel free to let me know down below, on Mastodon or on Bluesky!
“Bq qr, Yorqb! Qebk cxii, Zxbpxo.”
Julius Caesar was a Roman, speaking Latin…so I’ll stick to the latin letters for the scope of this little blog post.↩︎
The Complete Works of William Shakespeare, https://shakespeare.mit.edu↩︎
Act 2, Scene 2 in Shakespeare’s play, cited above.↩︎
pun intended↩︎
@misc{gebhard2025,
author = {Gebhard, Christian},
title = {The {Ides} of {March}},
date = {2025-08-27},
url = {https://christiangebhard.com/posts/2025-08-26-julia-CO-06/},
langid = {en}
}