Shift Cipher Implementation
Implementation of shift cipher for both printable ASCII and binary input with encryption and decryption capabilities.
Overview
Lab 1 project implementing the classic shift cipher (Caesar cipher) algorithm for both printable ASCII characters and binary data. The implementation demonstrates fundamental cryptographic concepts including modular arithmetic, character encoding, and basic encryption/decryption workflows. Includes a flag-finding challenge component that applies cipher-breaking techniques.
As part of this exercise, we were tasked with implementing a Shift Cipher encryption and decryption program in Python. The goal was to read a given text file, apply a shift cipher using a specified key, and produce an encrypted (or decrypted) output file depending on the selected mode.
The input text file, sherlock.txt, contained the following excerpt from a Sherlock Holmes novel:
We had to write a Python program (ex1.py) that could:
- Load a given .txt file.
- Encrypt it with a specified key.
- Output the encrypted (ciphered) text.
- Provide a decryption mode to reverse the process.
Technologies Used
Key Features
Shift cipher encryption for printable ASCII input
Binary shift cipher implementation
Encryption and decryption functions
Flag finding challenge solver
Brute force attack implementation
Frequency analysis tools
Showing 6 of 7 features
Implementation Details
Command-Line Argument Validation
The program is executed using the following command-line format:
Before performing any encryption or decryption, the program first checks that all required command-line arguments are provided. This ensures that the user has correctly specified the input/output filenames, key, and mode. This validation prevents runtime errors and ensures that users follow the proper command format before the program proceeds.
Code Explanation
The code first checks if exactly 9 arguments are provided (program name + 8 arguments for 4 flags). It then parses these arguments into a dictionary for easy access. Next, it validates that all required flags (-i, -o, -k, -m) are present. Finally, it validates that the mode is either "encrypt" or "decrypt". This comprehensive validation ensures the program won't crash due to missing or invalid input.
File Validation and Loading
Next, we ensure that the input file exists and can be read properly. Two helper functions are used: 1. To check whether the .txt file exists. 2. To confirm that the file contains printable characters only.
These checks prevent the program from crashing on missing or corrupted files, ensuring the text is valid before encryption.
Code Explanation
The file_exists() function uses os.path.isfile() to verify the file exists. The is_printable_file() function reads the file and checks each character to ensure it falls within the printable ASCII range (32-126), with exceptions for newlines, carriage returns, and tabs. The load_file() function combines these checks and returns the file contents only if all validations pass. This prevents the cipher from processing invalid input data.
Shift Cipher Encryption and Decryption
The Shift Cipher (also known as the Caesar Cipher) works by shifting each printable character by a given key value along the ASCII range. If the shift goes beyond the printable range, it wraps around to the start.
In encryption mode, characters are shifted forward by key. In decryption mode, characters are shifted backward by key.
This ensures full reversibility — decrypting the encrypted output with the same key restores the original text.
Code Explanation
The shift_cipher() function implements the core algorithm. It defines the printable ASCII range (32-126, giving 95 characters). For each character, it: 1. Gets the ASCII value using ord() 2. Normalizes it to 0-94 range by subtracting MIN_PRINTABLE 3. Applies the shift using modulo arithmetic to handle wraparound 4. For encryption: (normalized + key) % 95 5. For decryption: (normalized - key) % 95 6. Converts back to ASCII by adding MIN_PRINTABLE and using chr() The modulo operation ensures that if a shift goes beyond 126, it wraps back to 32, maintaining the cipher within the printable range. This makes the cipher fully reversible - encrypting with key K and then decrypting with the same key K returns the original text.
Shift Cipher for Binary Input
We now need to attempt shift cipher with binary files instead of just printable text outputs. This allows us to encrypt any type of file - images, executables, compressed files, etc.
Using the same command-line interface and validation as above, this time instead of just shifting over printable ASCII characters, we work directly with raw bytes. The implementation converts bytes to a formatted hex string for visualization and applies the shift to each byte value:
Code Explanation
The binary shift cipher works at the byte level rather than character level: 1. **bytes_to_hex_string()**: Creates a hex dump visualization similar to tools like hexdump or xxd. It displays bytes in hexadecimal with their ASCII representation, making it easy to inspect binary data. 2. **encrypt()/decrypt()**: These functions operate on raw bytes (0-255) instead of printable ASCII (32-126). Each byte is shifted using modulo 256 arithmetic: - Encryption: (byte + key) % 256 - Decryption: (byte - key) % 256 3. **Binary file handling**: Files are opened with 'rb' (read binary) and 'wb' (write binary) modes to handle any file type, not just text. 4. **Output**: Two files are generated: - The encrypted/decrypted binary file (same format as input) - A .txt file with hex dump for analysis This approach works on ANY file type because it operates at the byte level. An encrypted image remains a valid image format (though visually scrambled), and can be perfectly restored by decryption. The 8-bit arithmetic (0-255 range) ensures all byte values remain valid after transformation.
Challenges
Understanding modular arithmetic for wraparound behavior, handling edge cases in ASCII encoding, implementing efficient brute force attack strategies for cipher breaking.
Outcome & Impact
Successfully implemented robust shift cipher with both ASCII and binary support, demonstrated cipher vulnerability through brute force analysis.
How I Grew
Mastered fundamental concepts of symmetric encryption
Learned modular arithmetic applications in cryptography
Understood the weakness of simple substitution ciphers
Gained experience in cipher breaking techniques
Developed skills in handling different encoding schemes
Try It Yourself
Output will appear here...
Works with letters, numbers, and special characters. Try "Hello World!" with key 3.