Creating a Rolling Cipher using a function

Viewed 290

I'm trying to write a function that is supposed to take a string like "abcd" and move the letter up or down by a certain number.

rolling_cipher("abcd", 1) ➞ "bcde"

Here is my code so far:

import string


def rolling_cipher(String, num):
    letters = string.ascii_lowercase
    print(letters)

    String = String.index(string)


rolling_cipher("abcd", 2)
3 Answers

This is a possible solution:

from string import ascii_lowercase

def rolling_cipher(s, n):
    idx = ascii_lowercase.index(s)
    new_idx = (idx + n) % len(ascii_lowercase)
    l = new_idx + len(s) - len(ascii_lowercase)
    a1 = ascii_lowercase[new_idx: new_idx + len(s)]
    a2 = '' if l <= 0 else ascii_lowercase[: l]
    return a1 + a2

Examples:

>>> rolling_cipher('abcd', 3)
'defg'
>>> rolling_cipher('rst', 6)
'xyz'
>>> rolling_cipher('rst', 8)
'zab'
>>> rolling_cipher('rst', 33)
'yza'

You might alternatively want to use deque:

from collections import deque
from string import ascii_lowercase

def rolling_cipher(s, n):
    d = deque(ascii_lowercase)
    d.rotate(-ascii_lowercase.index(s) - n)
    return ''.join(list(d)[:len(s)])
                          

Just for fun, here's a one-liner that will do the trick:

import string

l = string.ascii_lowercase
s = 'eggs'

''.join(l[(l.rindex(i) + n) % 26] for i in s)

Output:

n = 1
>>> 'fhht'

n = 5
>>> 'jllx'

n = 100  # Same as -4
>>> 'acco'

n = -26
>>> 'eggs'

And, if you want to wrap it in a function:

def rolling(s, n) -> str:
    """Caesar cipher.
    
    Args:
        s (str): String to be encrypted.
        n (int): Shift value.
        
    Returns:
        Encrypted string.
    
    """
    return ''.join(l[(l.rindex(i) + n) % 26] for i in s)

Output:

rolling('eggs', -5)
>>> 'zbbn'

Try something like this

def foo(str:string, idx:int):
    print(string.ascii_lowercase[idx: len(str) + idx])
Related