How to Implement a Simple Caesar Cipher in Batch Script
The Caesar cipher is one of the oldest and simplest encryption techniques. It is a substitution cipher where each letter in the plaintext is shifted a certain number of places down the alphabet. For instance, with a shift of 1, 'A' becomes 'B', 'B' becomes 'C', and so on. Understanding and implementing it in a Batch script is a classic exercise in algorithmic logic and string manipulation.
In this guide, we will demonstrate how to build an interactive Caesar cipher encoder and decoder in Batch.
The Strategy: Alphabet Arrays and Index Shifting
Native Batch scripts do not have a built-in .indexOf() function for strings. To build a Caesar cipher:
- Define the alphabet sequence as a string.
- Accept a numeric shift key from the user (e.g., 3).
- Loop through the input string character by character.
- For each character, find its position in the alphabet string.
- Apply the shift key, handle wrap-around (using modulo arithmetic), and retrieve the new character.
- Append it to the output string.
Implementation Script
@echo off
setlocal EnableDelayedExpansion
:: 1. Ask for input
set /p "userInput=Enter text to encrypt: "
set /p "shiftKey=Enter shift number (e.g., 3): "
:: Define the alphabet maps (both upper and lower cases)
set "charsLower=abcdefghijklmnopqrstuvwxyz"
set "charsUpper=ABCDEFGHIJKLMNOPQRSTUVWXYZ"
set "output="
set "idx=0"
:: 2. Determine input string length
call :string_length "%userInput%" len
:: 3. Process each character
set /a "lastIdx=len - 1"
for /l %%A in (0,1,!lastIdx!) do (
set "currentChar=!userInput:~%%A,1!"
set "matched=0"
:: 4. Search in Lowercase Alphabet
for /l %%B in (0,1,25) do (
if "!currentChar!"=="!charsLower:~%%B,1!" if "!matched!"=="0" (
:: Calculate new index with modulo 26 for wrap-around
set /a "newIndex=((%%B + shiftKey) %% 26 + 26) %% 26"
:: Append shifted character
for %%N in (!newIndex!) do set "output=!output!!charsLower:~%%N,1!"
set "matched=1"
)
)
:: 5. Search in Uppercase Alphabet
if "!matched!"=="0" (
for /l %%B in (0,1,25) do (
if "!currentChar!"=="!charsUpper:~%%B,1!" if "!matched!"=="0" (
set /a "newIndex=((%%B + shiftKey) %% 26 + 26) %% 26"
for %%N in (!newIndex!) do set "output=!output!!charsUpper:~%%N,1!"
set "matched=1"
)
)
)
:: 6. If not a letter (space, number, punctuation), keep original
if "!matched!"=="0" (
set "output=!output!!currentChar!"
)
)
echo.
echo ==========================================
echo ORIGINAL: !userInput!
echo SHIFT : !shiftKey!
echo RESULT : !output!
echo ==========================================
pause
exit /b
:string_length
:: Usage: call :string_length "string" variableName
setlocal
set "s=%~1"
set "sLen=0"
if defined s (
for /l %%I in (0,1,8191) do (
if not "!s:~%%I,1!"=="" (set /a "sLen+=1") else (goto :doneLen)
)
)
:doneLen
endlocal & set "%2=%sLen%"
exit /b
How It Works
- Modulo Arithmetic: The core logic lies in
set /a "newIndex=((%%B + shiftKey) %% 26 + 26) %% 26". The double-modulo pattern((x % 26) + 26) % 26ensures the result is always a positive index between 0 and 25, regardless of whether the intermediate value is negative. - Negative Shifts (Decryption): The script works for decryption as well. If you provide a negative shift value (e.g.,
-3), the double-modulo expression correctly wraps backwards through the alphabet in a single step. - Character Preservation: The script loops 26 times to find a match. If a match is completely missed (because the character is a space, comma, or number), that character is appended as-is.
- Match Guard: The
if "!matched!"=="0"check on the same line as the character comparison prevents a character from being shifted multiple times when matching successive alphabet positions within the inner loop.
Simplifying with a PowerShell Bridge
Batch is notorious for its sluggish character-by-character loops. For encrypting huge log files, using PowerShell's native object array iteration is thousands of times faster.
The PowerShell bridge passes user input directly into a command string. Avoid using characters that break quoting (such as single quotes, double quotes, backticks, or dollar signs) in the input text, or add proper escaping for production use.
@echo off
setlocal EnableDelayedExpansion
set /p "str=Enter string: "
set /p "shift=Enter shift: "
:: Build the PowerShell command separately for readability
set "psCmd=$s='%str%';"
set "psCmd=!psCmd! $k=%shift%;"
set "psCmd=!psCmd! $arr=$s.ToCharArray();"
set "psCmd=!psCmd! for($i=0;$i -lt $arr.Length;$i++){"
set "psCmd=!psCmd! [int]$c=$arr[$i];"
set "psCmd=!psCmd! if($c -ge 97 -and $c -le 122){"
set "psCmd=!psCmd! $arr[$i]=[char]((($c-97+$k)%%26+26)%%26+97)"
set "psCmd=!psCmd! } elseif($c -ge 65 -and $c -le 90){"
set "psCmd=!psCmd! $arr[$i]=[char]((($c-65+$k)%%26+26)%%26+65)"
set "psCmd=!psCmd! }"
set "psCmd=!psCmd! };"
set "psCmd=!psCmd! -join $arr"
:: Delegate to PowerShell
for /f "delims=" %%I in ('powershell -NoProfile -Command "!psCmd!"') do set "encoded=%%I"
echo Result: !encoded!
pause
Why Implement a Caesar Cipher?
- Computer Science Fundamentals: It serves as an exceptional training ground for understanding arrays, indices, bounds checking, and integer wrap-around.
- Basic Data Masking: While not cryptographically secure, applying a cipher to a text file prevents casual end-users from reading connection strings or API tokens in plain-text at first glance.
- Puzzle Generation: Creating automated riddles and geocaching clues locally over an entire directory of text files for a team-building exercise.
Conclusion
Building a Caesar Cipher demonstrates advanced control flow string manipulation within Windows Batch. Dealing with character positioning, simulating arrays via substrings, and using modulo arithmetic builds a formidable foundation for writing more sophisticated data-transformation scripts. While it won't stop a dedicated hacker, the Caesar cipher remains an elegant tool for basic text obfuscation.