如何确保Python替换密码解码中解密消息的增量变化?

0 投票
2 回答
40 浏览
提问于 2025-04-12 14:40

我正在开发一个解密的方法,想让用户手动输入来解密一句话。

import random


class Cryptography:
    def __init__(self, input_file):
        self.input_file = input_file
        with open(self.input_file, 'r+') as file:
            self.content = file.read()
        self.sentence = ''
        self.code = {
            'A': 'A', 'Ą': 'A', 'B': 'A', 'C': 'A',
            'Ć': 'A', 'D': 'A', 'E': 'A', 'Ę': 'A',
            'F': 'A', 'G': 'A', 'H': 'A', 'I': 'A',
            'J': 'A', 'K': 'A', 'L': 'A', 'Ł': 'A',
            'M': 'A', 'N': 'A', 'Ń': 'A', 'O': 'A',
            'Ó': 'A', 'P': 'A', 'R': 'A', 'S': 'A',
            'Ś': 'A', 'T': 'A', 'U': 'A', 'W': 'A',
            'Y': 'A', 'Z': 'A', 'Ż': 'A', 'Ź': 'A',
        }
        self.replaced_sentence = ''
        self.welcome = '\nWITAJ\nMASZ TERAZ OKAZJE ODSZYFROWAĆ POWYŻSZĄ WIADOMOSĆ\nZA KAŻDYM RAZEM JAK ZAMIENISZ ' \
                       'LITERKI WYSWIETLONA ZOSTANIE\nCZĘŚCIOWO ODSZYFROWANA WIADOMOŚĆ.\nPOWODZENIA!\n '

    # repair converts whatever is in self.content to self.sentence, so it is one line of text without large whitespaces.
    def repair(self):
        for char in self.content:
            if char == '\n':
                char = char.replace('\n', ' ')
            char = char.capitalize()
            self.sentence += char
        self.sentence = " ".join(self.sentence.split())
        print(self.sentence)

    def encrypt(self):
        numbers = list(range(32))
        random.shuffle(numbers)
        letters = list(self.code.keys())
        encrypted_code = {}
        for i, letter in enumerate(letters):
            encrypted_code[letter] = letters[numbers[i]]
        self.code = encrypted_code
        print(f"Encrypted successfully!")

    def transform(self):
        special_char = [' ', ',', '!', '.', '(', ')', ';',]
        for char in self.sentence:
            if char in special_char:
                replaced_char = char
            else:
                replaced_char = self.code.get(char)
            self.replaced_sentence += replaced_char

    def decode(self):
        guessed_sentence = self.replaced_sentence
        spec_char = zip([' ', ',', '!', '.', '(', ')', ';'], [' ', ',', '!', '.', '(', ')', ';'])
        self.code.update(spec_char)
        while True:
            print(guessed_sentence)
            guess = input('please type eg. A = S : ')
            guess = guess.strip()
            guess = guess.replace(' ', '')
            letter1 = guess[0].upper()
            letter2 = guess[2].upper()
            char_mapping = self.code
            char_mapping[letter1] = letter2
            old_string = self.replaced_sentence
            guessed_sentence = ''
            for char in old_string:
                guessed_sentence += char_mapping[char]
            if guessed_sentence == self.sentence:
                break


test = Cryptography('message')
test.repair()
test.encrypt()
test.transform()
test.decode()
  1. __init__(self, input_file): 这个方法用来初始化一个加密类,输入一个文件。它会读取这个文件的内容,并设置一些属性,比如sentence(句子)、code(编码)、replaced_sentence(替换后的句子)和welcome(欢迎信息)。

  2. repair(self): 这个方法会处理从输入文件中读取的内容,去掉多余的空格,把字母大写,然后把处理后的句子存储在self.sentence这个属性里。

  3. encrypt(self): 这个方法会根据在self.code中提供的原始映射,生成一个随机的字母映射,从而对消息进行加密。

  4. transform(self): 这个方法会使用在encrypt方法中生成的加密映射,把原始句子转变为加密后的句子,并把结果存储在self.replaced_sentence中。

  5. decode(self): 这个方法开始解密过程。它会提示用户输入字母替换,然后把这些替换应用到加密消息上,打印出部分解密的消息,直到它与原始句子匹配。

self.welcome在这个版本中没有用到,只是为了美观,没什么大不了的。

我想要的输出是显示加密消息,但只有在实施了更改的地方才会有变化。

为了更清楚,这里是整个函数的输出(句子是波兰语,但我认为这不会影响理解):

LITWO! OJCZYZNO MOJA! TY JESTEŚ JAK ZDROWIE.
Encrypted successfully!
UDŹHĘ! ĘJZMŻMEĘ TĘJŃ! ŹŻ JAGŹAI JŃŁ MBĆĘHDA.
please type eg. A = S : U=L
LBCRL! LJMTWTAL ŹLJÓ! CW JŃOCŃD JÓF TĄSLRBŃ.
please type eg. A = S : D=I
LICRL! LJMTWTAL ŹLJÓ! CW JŃOCŃD JÓF TĄSLRIŃ.
please type eg. A = S : Ź=T
LITRL! LJMTWTAL ŹLJÓ! TW JŃOTŃD JÓF TĄSLRIŃ.
please type eg. A = S : 

正如你所看到的,每次我做出更改时,加密消息都会变化。这是我追求的结果:

LITWO! OJCZYZNO MOJA! TY JESTEŚ JAK ZDROWIE.
Encrypted successfully!
UDŹHĘ! ĘJZMŻMEĘ TĘJŃ! ŹŻ JAGŹAI JŃŁ MBĆĘHDA.
please type eg. A = S : U=L
LDŹHĘ! ĘJZMŻMEĘ TĘJŃ! ŹŻ JAGŹAI JŃŁ MBĆĘHDA.
please type eg. A = S : D=I
LIŹHĘ! ĘJZMŻMEĘ TĘJŃ! ŹŻ JAGŹAI JŃŁ MBĆĘHIA.
please type eg. A = S : Ź=T
LITHĘ! ĘJZMŻMEĘ TĘJŃ! TŻ JAGTAI JŃŁ MBĆĘHIA.
please type eg. A = S : 

我该如何修改代码,以便产生我想要的结果呢?

2 个回答

0

我修改了Mark Tolonen的回答,把解码函数改成了我想要的样子:

import random

class Cryptography:
    def __init__(self, message):
        self.sentence = message.upper()
        self.alphabet = 'AĄBCĆDEĘFGHIJKLŁMNŃOÓPRSŚTUWYZŻŹ'
        keys = [ord(a) for a in self.alphabet]  # keys must be ordinals
        values = list(keys)  # need mutable list for shuffle
        random.shuffle(values)
        self.code = dict(zip(keys, values))  # build translation table
        self.replaced_sentence = self.sentence.translate(self.code)  # translate
        print(f'Encrypted successfully!')

    def decode(self):
        guessed_sentence = self.replaced_sentence
        # Lists will store each character separately providing information about place and character
        list_enc = []
        list_guess = []

        for i in self.replaced_sentence:
            list_enc += i

        for i in guessed_sentence:
            list_guess += i

        # hits will store temporarely data about which coordinate of the list to change
        hits = []

        print(self.replaced_sentence)
        while True:
            guess = input('please type eg. A = S : ')
            guess = guess.strip()
            guess = guess.replace(' ', '')
            letter1 = guess[0].upper()
            letter2 = guess[2].upper()

            # this loop searches for places where letters should be changed, and appends these coordinates to hits
            for i in range(len(list_enc)):
                if letter1 == list_enc[i]:
                    hit = i
                    hits.append(hit)

            # this loop changes letters in list_guess in designated coordinantes in hits
            for i in range(len(hits)):
                list_guess[hits[i]] = letter2

            # join back list to string
            guessed_sentence1 = ''.join(list_guess)

            # reset hits to empty list
            hits = []

            print(guessed_sentence1)
            if guessed_sentence == self.sentence:
                print(f"{guessed_sentence}\nCONGRATULATIONS!")
                break


test = Cryptography('Litwo! Ojczyzno moja! Ty jesteś jak zdrowie.')
test.decode()

输出结果看起来是这样的:

Encrypted successfully!
LITWO! OJCZYZNO MOJA! TY JESTEŚ JAK ZDROWIE.
WŚZCŁ! ŁJSŹYŹŃŁ RŁJĆ! ZY JFNZFU JĆB ŹDGŁCŚF.
please type eg. A = S : W=L
LŚZCŁ! ŁJSŹYŹŃŁ RŁJĆ! ZY JFNZFU JĆB ŹDGŁCŚF.
please type eg. A = S : Ś=I
LIZCŁ! ŁJSŹYŹŃŁ RŁJĆ! ZY JFNZFU JĆB ŹDGŁCIF.
please type eg. A = S : Z=T
0

这个解决方案经过了大量的改进。关键在于使用 str.translate 这个功能,配合一个当前的替换列表,每次从加密信息中生成部分解码的信息。因为把一个字母翻译成比如说 'A' 可能会和没有翻译的 'A' 混淆,所以我每次都会打印出当前的翻译和原句,这样对我来说会更容易理解:

import random

class Cryptography:
    def __init__(self, message):
        self.sentence = message.upper()
        self.alphabet = 'AĄBCĆDEĘFGHIJKLŁMNŃOÓPRSŚTUWYZŻŹ'
        keys = [ord(a) for a in self.alphabet] # keys must be ordinals
        values = list(keys)  # need mutable list for shuffle
        random.shuffle(values)
        self.code = dict(zip(keys, values))  # build translation table
        self.replaced_sentence = self.sentence.translate(self.code)  # translate
        print(f'Encrypted successfully!')

    def decode(self):
        guessed_sentence = self.replaced_sentence
        # build up a translation table.  Start with hyphens for unknowns.
        guessed_code = dict(zip([ord(a) for a in self.alphabet], '-' * len(self.alphabet)))
        while True:
            print(self.replaced_sentence)
            guess = input('please type eg. A = S : ')
            guess = guess.strip()
            guess = guess.replace(' ', '')
            letter1 = guess[0].upper()
            letter2 = guess[2].upper()
            guessed_code[ord(letter1)] = ord(letter2)  # update translation table
            guessed_sentence = self.replaced_sentence.translate(guessed_code)  # translate
            print(guessed_sentence)
            if guessed_sentence == self.sentence:
                print('Success!')
                break

test = Cryptography('Litwo! Ojczyzno moja! Ty jesteś jak zdrowie.')
test.decode()

输出结果:

Encrypted successfully!
SWŹJI! IOZBMBFI KIOŁ! ŹM OARŹAY OŁH BĆĘIJWA.
please type eg. A = S : s=l
L----! -------- ----! -- ------ --- -------.
SWŹJI! IOZBMBFI KIOŁ! ŹM OARŹAY OŁH BĆĘIJWA.
please type eg. A = S : w=i
LI---! -------- ----! -- ------ --- -----I-.
SWŹJI! IOZBMBFI KIOŁ! ŹM OARŹAY OŁH BĆĘIJWA.
please type eg. A = S : Ź=i
LII--! -------- ----! I- ---I-- --- -----I-.
SWŹJI! IOZBMBFI KIOŁ! ŹM OARŹAY OŁH BĆĘIJWA.
please type eg. A = S : Ź=t
LIT--! -------- ----! T- ---T-- --- -----I-.
SWŹJI! IOZBMBFI KIOŁ! ŹM OARŹAY OŁH BĆĘIJWA.
please type eg. A = S : j=w
LITW-! -------- ----! T- ---T-- --- ----WI-.
SWŹJI! IOZBMBFI KIOŁ! ŹM OARŹAY OŁH BĆĘIJWA.
please type eg. A = S : i=o
LITWO! O------O -O--! T- ---T-- --- ---OWI-.
SWŹJI! IOZBMBFI KIOŁ! ŹM OARŹAY OŁH BĆĘIJWA.
please type eg. A = S : o=j
LITWO! OJ-----O -OJ-! T- J--T-- J-- ---OWI-.
SWŹJI! IOZBMBFI KIOŁ! ŹM OARŹAY OŁH BĆĘIJWA.
please type eg. A = S : z=c
LITWO! OJC----O -OJ-! T- J--T-- J-- ---OWI-.
SWŹJI! IOZBMBFI KIOŁ! ŹM OARŹAY OŁH BĆĘIJWA.
please type eg. A = S : b=z
LITWO! OJCZ-Z-O -OJ-! T- J--T-- J-- Z--OWI-.
SWŹJI! IOZBMBFI KIOŁ! ŹM OARŹAY OŁH BĆĘIJWA.
please type eg. A = S : m=y
LITWO! OJCZYZ-O -OJ-! TY J--T-- J-- Z--OWI-.
SWŹJI! IOZBMBFI KIOŁ! ŹM OARŹAY OŁH BĆĘIJWA.
please type eg. A = S : f=n
LITWO! OJCZYZNO -OJ-! TY J--T-- J-- Z--OWI-.
SWŹJI! IOZBMBFI KIOŁ! ŹM OARŹAY OŁH BĆĘIJWA.
please type eg. A = S : k=m
LITWO! OJCZYZNO MOJ-! TY J--T-- J-- Z--OWI-.
SWŹJI! IOZBMBFI KIOŁ! ŹM OARŹAY OŁH BĆĘIJWA.
please type eg. A = S : Ł=a
LITWO! OJCZYZNO MOJA! TY J--T-- JA- Z--OWI-.
SWŹJI! IOZBMBFI KIOŁ! ŹM OARŹAY OŁH BĆĘIJWA.
please type eg. A = S : a=e
LITWO! OJCZYZNO MOJA! TY JE-TE- JA- Z--OWIE.
SWŹJI! IOZBMBFI KIOŁ! ŹM OARŹAY OŁH BĆĘIJWA.
please type eg. A = S : r=s
LITWO! OJCZYZNO MOJA! TY JESTE- JA- Z--OWIE.
SWŹJI! IOZBMBFI KIOŁ! ŹM OARŹAY OŁH BĆĘIJWA.
please type eg. A = S : y=ś
LITWO! OJCZYZNO MOJA! TY JESTEŚ JA- Z--OWIE.
SWŹJI! IOZBMBFI KIOŁ! ŹM OARŹAY OŁH BĆĘIJWA.
please type eg. A = S : h=k
LITWO! OJCZYZNO MOJA! TY JESTEŚ JAK Z--OWIE.
SWŹJI! IOZBMBFI KIOŁ! ŹM OARŹAY OŁH BĆĘIJWA.
please type eg. A = S : Ć=d
LITWO! OJCZYZNO MOJA! TY JESTEŚ JAK ZD-OWIE.
SWŹJI! IOZBMBFI KIOŁ! ŹM OARŹAY OŁH BĆĘIJWA.
please type eg. A = S : Ę=r
LITWO! OJCZYZNO MOJA! TY JESTEŚ JAK ZDROWIE.
Success!

撰写回答