this algorithm uses the caesar cipher algorithm but removes the option to use brute force to decrypt the message the passcode is a random password from the selection buffer of 1 uppercase letters of the english alphabet 2 lowercase letters of the english alphabet 3 digits from 0 to 9 using unique characters from the passcode the normal list of characters that can be allowed in the plaintext is pivoted and shuffled refer to docstring of makekeylist to learn more about the shuffling then using the passcode a number is calculated which is used to encrypt the plaintext message with the normal shift cipher method only in this case the reference to look back at while decrypting is shuffled each cipher object can possess an optional argument as passcode without which a new passcode is generated for that object automatically cip1 shuffledshiftcipher d4usr9twxw9wmd cip2 shuffledshiftcipher initializes a cipher object with a passcode as it s entity note no new passcode is generated if user provides a passcode while creating the object return passcode of the cipher object mutates the list by changing the sign of each alternate element param iterlist takes a list iterable return the mutated list creates a random password from the selection buffer of 1 uppercase letters of the english alphabet 2 lowercase letters of the english alphabet 3 digits from 0 to 9 rtype list return a password of a random length between 10 to 20 shuffles the ordered character choices by pivoting at breakpoints breakpoints are the set of characters in the passcode eg if abcdefghijklmnopqrstuvwxyz are the possible characters and camera is the passcode then breakpoints a c e m r sorted set of characters from passcode shuffled parts a cb ed mlkjihgf rqpon zyxwvuts shuffled keylist acbedmlkjihgfrqponzyxwvuts shuffling only 26 letters of the english alphabet can generate 26 combinations for the shuffled list in the program we consider a set of 97 characters including letters digits punctuation and whitespaces thereby creating a possibility of 97 combinations which is a 152 digit number in itself thus diminishing the possibility of a brute force approach moreover shift keys even introduce a multiple of 26 for a brute force approach for each of the already 97 combinations keylistoptions contain nearly all printable except few elements from string whitespace creates points known as breakpoints to break the keylistoptions at those points and pivot each substring algorithm for creating a new shuffled list keysl out of keylistoptions checking breakpoints at which to pivot temporary sublist and add it into keysl returning a shuffled keysl to prevent brute force guessing of shift key sum of the mutated list of ascii values of all characters where the mutated list is the one returned by negpos performs shifting of the encodedmessage w r t the shuffled keylist to create the decodedmessage ssc shuffledshiftcipher 4pyixyqeqzr44 ssc decryptd1z6 5z 5z z zp 5 z hello this is a modified caesar cipher decoding shift like caesar cipher algorithm implementing negative shift or reverse shift or left shift performs shifting of the plaintext w r t the shuffled keylist to create the encodedmessage ssc shuffledshiftcipher 4pyixyqeqzr44 ssc encrypt hello this is a modified caesar cipher d1z6 5z 5z z zp 5 z encoding shift like caesar cipher algorithm implementing positive shift or forward shift or right shift testendtoend hello this is a modified caesar cipher this algorithm uses the caesar cipher algorithm but removes the option to use brute force to decrypt the message the passcode is a random password from the selection buffer of 1 uppercase letters of the english alphabet 2 lowercase letters of the english alphabet 3 digits from 0 to 9 using unique characters from the passcode the normal list of characters that can be allowed in the plaintext is pivoted and shuffled refer to docstring of __make_key_list to learn more about the shuffling then using the passcode a number is calculated which is used to encrypt the plaintext message with the normal shift cipher method only in this case the reference to look back at while decrypting is shuffled each cipher object can possess an optional argument as passcode without which a new passcode is generated for that object automatically cip1 shuffledshiftcipher d4usr9twxw9wmd cip2 shuffledshiftcipher initializes a cipher object with a passcode as it s entity note no new passcode is generated if user provides a passcode while creating the object return passcode of the cipher object mutates the list by changing the sign of each alternate element param iterlist takes a list iterable return the mutated list creates a random password from the selection buffer of 1 uppercase letters of the english alphabet 2 lowercase letters of the english alphabet 3 digits from 0 to 9 rtype list return a password of a random length between 10 to 20 shuffles the ordered character choices by pivoting at breakpoints breakpoints are the set of characters in the passcode eg if abcdefghijklmnopqrstuvwxyz are the possible characters and camera is the passcode then breakpoints a c e m r sorted set of characters from passcode shuffled parts a cb ed mlkjihgf rqpon zyxwvuts shuffled __key_list acbedmlkjihgfrqponzyxwvuts shuffling only 26 letters of the english alphabet can generate 26 combinations for the shuffled list in the program we consider a set of 97 characters including letters digits punctuation and whitespaces thereby creating a possibility of 97 combinations which is a 152 digit number in itself thus diminishing the possibility of a brute force approach moreover shift keys even introduce a multiple of 26 for a brute force approach for each of the already 97 combinations key_list_options contain nearly all printable except few elements from string whitespace creates points known as breakpoints to break the key_list_options at those points and pivot each substring algorithm for creating a new shuffled list keys_l out of key_list_options checking breakpoints at which to pivot temporary sublist and add it into keys_l returning a shuffled keys_l to prevent brute force guessing of shift key sum of the mutated list of ascii values of all characters where the mutated list is the one returned by __neg_pos performs shifting of the encoded_message w r t the shuffled __key_list to create the decoded_message ssc shuffledshiftcipher 4pyixyqeqzr44 ssc decrypt d 1z6 5z 5z z zp 5 z hello this is a modified caesar cipher decoding shift like caesar cipher algorithm implementing negative shift or reverse shift or left shift performs shifting of the plaintext w r t the shuffled __key_list to create the encoded_message ssc shuffledshiftcipher 4pyixyqeqzr44 ssc encrypt hello this is a modified caesar cipher d 1z6 5z 5z z zp 5 z encoding shift like caesar cipher algorithm implementing positive shift or forward shift or right shift test_end_to_end hello this is a modified caesar cipher
from __future__ import annotations

import random
import string


class ShuffledShiftCipher:
    

    def __init__(self, passcode: str | None = None) -> None:
        
        self.__passcode = passcode or self.__passcode_creator()
        self.__key_list = self.__make_key_list()
        self.__shift_key = self.__make_shift_key()

    def __str__(self) -> str:
        
        return "".join(self.__passcode)

    def __neg_pos(self, iterlist: list[int]) -> list[int]:
        
        for i in range(1, len(iterlist), 2):
            iterlist[i] *= -1
        return iterlist

    def __passcode_creator(self) -> list[str]:
        
        choices = string.ascii_letters + string.digits
        password = [random.choice(choices) for _ in range(random.randint(10, 20))]
        return password

    def __make_key_list(self) -> list[str]:
        
        
        
        key_list_options = (
            string.ascii_letters + string.digits + string.punctuation + " \t\n"
        )

        keys_l = []

        
        
        breakpoints = sorted(set(self.__passcode))
        temp_list: list[str] = []

        
        for i in key_list_options:
            temp_list.extend(i)

            
            
            if i in breakpoints or i == key_list_options[-1]:
                keys_l.extend(temp_list[::-1])
                temp_list.clear()

        
        return keys_l

    def __make_shift_key(self) -> int:
        
        num = sum(self.__neg_pos([ord(x) for x in self.__passcode]))
        return num if num > 0 else len(self.__passcode)

    def decrypt(self, encoded_message: str) -> str:
        
        decoded_message = ""
  
        for i in encoded_message:
            position = self.__key_list.index(i)
            decoded_message += self.__key_list[
                (position - self.__shift_key) % -len(self.__key_list)
            ]

        return decoded_message

    def encrypt(self, plaintext: str) -> str:
        
        encoded_message = ""

        for i in plaintext:
            position = self.__key_list.index(i)
            encoded_message += self.__key_list[
                (position + self.__shift_key) % len(self.__key_list)
            ]

        return encoded_message


def test_end_to_end(msg: str = "Hello, this is a modified Caesar cipher") -> str:
    
    cip1 = ShuffledShiftCipher()
    return cip1.decrypt(cip1.encrypt(msg))


if __name__ == "__main__":
    import doctest

    doctest.testmod()