5 Ingenious Ways to Encrypt a String Using Vertical Cipher in Python

πŸ’‘ Problem Formulation: This article offers Python techniques for encrypting a string with a vertical cipher. The challenge involves rearranging the characters in a string vertically, according to a specified number of columns, then reading them row-wise to create the ciphered text. Imagine turning the input “security” into “sceruti” using 3 columns for encryption.

Method 1: Basic Vertical Cipher

The first method involves creating a function that takes the input string and the number of columns for the cipher. This method processes the string by padding it, if necessary, then constructs a list of strings by grouping characters into columns, finally joining them to get the encrypted text.

Here’s an example:

def vertical_cipher(text, columns):
    # Padding the text so that division by columns has no remainder
    padding = '-' * ((columns - len(text) % columns) % columns)
    padded_text = text + padding

    # Splitting the padded_text into equally sized chunks
    chunks = [padded_text[i:i+columns] for i in range(0, len(padded_text), columns)]

    # Reading the text vertically
    ciphered = ''.join([''.join(column) for column in zip(*chunks)]).replace('-','')
    return ciphered

encrypted_text = vertical_cipher('security', 3)
print(encrypted_text)

Output:

sceruti

This code snippet defines a function vertical_cipher that pads the input string if it isn’t perfectly divisible by the column count, then splits the input into equal-sized chunks. Characters are read vertically and concatenated, after which any padding is removed to produce the ciphered string.

Method 2: Using NumPy for Array Manipulation

In this method, we leverage NumPy’s array manipulation abilities to perform vertical ciphering. After converting the string into a NumPy array with a shape that matches the desired column count, the array is transposed and the characters are read row-wise to construct the cipher text.

Here’s an example:

import numpy as np

def vertical_cipher_numpy(text, columns):
    # Pad text to fit perfectly in the array
    pad_length = -len(text) % columns
    padded_text = text + ' ' * pad_length
    
    # Convert text into array and transpose it
    array = np.array(list(padded_text)).reshape(-1, columns).T
    encrypted = ''.join(array.ravel()).replace(' ', '')
    return encrypted

encrypted_text = vertical_cipher_numpy('security', 3)
print(encrypted_text)

Output:

sceruti

Using NumPy, the vertical_cipher_numpy function transforms the input string into an array, which is then rearranged column-wise and read row-wise to create the encrypted string. Excess padding spaces are removed during the final step.

Method 3: List Comprehension and Join

To apply a vertical cipher, this method employs list comprehension and the join method in Python. It cleverly uses ranges to access characters in columnar fashion and joins them to form the encrypted text. Padding characters are omitted directly in read operations.

Here’s an example:

def vertical_cipher_comp(text, columns):
    length = len(text)
    encrypted = ''.join([text[i::columns] for i in range(columns) if text[i::columns]])
    return encrypted

encrypted_text = vertical_cipher_comp('security', 3)
print(encrypted_text)

Output:

sceruti

This code sample defines a vertical_cipher_comp function that uses list comprehension to cipher the text vertically without needing to pad the input, as any shortfall simply results in shorter final slices.

Method 4: Using Python Zip and Itertools

The fourth method incorporates Python’s built-in zip function in combination with itertools.zip_longest to handle the vertical cipher. Instead of regular padding, the function uses fill values that are stripped in the final output.

Here’s an example:

from itertools import zip_longest

def vertical_cipher_zip(text, columns):
    args = [iter(text)] * columns
    encrypted = ''.join([c for c in itertools.chain(*zip_longest(*args, fillvalue='')) if c])
    return encrypted

encrypted_text = vertical_cipher_zip('security', 3)
print(encrypted_text)

Output:

sceruti

Through itertools.zip_longest, the function vertical_cipher_zip can work with input strings that do not perfectly divide into the column count, using an empty string as a fill value. It reads characters column by column and omits any fill value to create the ciphered text.

Bonus One-Liner Method 5: Compact Solution

For Python enthusiasts looking for the most concise implementation, this method outputs an encrypted string using a one-liner approach that leverages list comprehension and Python’s built-in functions succinctly.

Here’s an example:

vertical_cipher = lambda text, columns: ''.join(text[i::columns] for i in range(columns))

encrypted_text = vertical_cipher('security', 3)
print(encrypted_text)

Output:

sceruti

The one-liner defined as a lambda function, vertical_cipher, achieves vertical cipher encryption with minimal code. By iterating column indices from 0 to columns-1, it slices and concatenates the string efficiently without padding.

Summary/Discussion

  • Method 1: Basic Vertical Cipher. Simple implementation. Requires manual string padding. Easy to understand.
  • Method 2: Using NumPy for Array Manipulation. Effective for large data sets. Introduces dependency on NumPy. Makes use of powerful array handling functions.
  • Method 3: List Comprehension and Join. Pythonic and concise. Avoids explicit padding but may be less readable for beginners.
  • Method 4: Using Python Zip and Itertools. Robust approach. More complex code. Handles different string lengths elegantly.
  • Bonus One-Liner Method 5: Compact Solution. Very succinct. Great for quick scripts. Less readable and potentially less flexible for modifications.