rot_13 — ROT13 Cipher
Allowed functions: write
Write a program that takes a string and displays it, replacing each of its letters by the letter 13 spaces ahead in alphabetical order.
z becomes m and Z becomes M. Case remains unaffected.
The output will be followed by a newline. If the number of arguments is not 1, the program displays a newline.
Examples
$>./rot_13 "abc"
nop
$>./rot_13 "My horse is Amazing." | cat -e
Zl ubefr vf Nznmvat.$
$>./rot_13 "AkjhZ zLKIJz , 23y " | cat -e
NxwuM mYXVWm , 23l $
$>./rot_13 | cat -e
$
Solution
Download rot_13.c#include <unistd.h>
int main(int ca, char **v) {
if (ca != 2) {
write(1, "\n", 1);
return 0;
}
char *str = v[1];
char c;
while (*str) {
c = *str;
if ((*str >= 'a' && *str <= 'z') || (*str >= 'A' && *str <= 'Z'))
c = *str + 13 - 26 * (*str % 32 > 13);
write(1, &c, 1);
str++;
}
write(1, "\n", 1);
return 0;
}
How It Works
Goal: Encode a string by replacing each letter with the letter 13 positions ahead in the alphabet.
Approach: Add 13 to each letter's ASCII value, and subtract 26 if it would wrap past 'z' or 'Z', using a modulo trick.
Step by step:
- If argument count is not 2, print a newline and exit.
- For each character, check if it is a letter (uppercase or lowercase).
- If it is a letter, compute the shifted character: add 13 and subtract 26 if the letter's position in the alphabet (
*str % 32) is greater than 13 (meaning it would overflow past 'z' or 'Z'). - Write the resulting character (shifted or original) to stdout.
Key concept: ASCII arithmetic and modulo for wrapping — using % 32 to get a letter's 1-based position in the alphabet regardless of case, enabling a single expression to handle wrap-around.