如何确保Python替换密码解码中解密消息的增量变化?
我正在开发一个解密的方法,想让用户手动输入来解密一句话。
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()
__init__(self, input_file)
: 这个方法用来初始化一个加密类,输入一个文件。它会读取这个文件的内容,并设置一些属性,比如sentence
(句子)、code
(编码)、replaced_sentence
(替换后的句子)和welcome
(欢迎信息)。repair(self)
: 这个方法会处理从输入文件中读取的内容,去掉多余的空格,把字母大写,然后把处理后的句子存储在self.sentence
这个属性里。encrypt(self)
: 这个方法会根据在self.code
中提供的原始映射,生成一个随机的字母映射,从而对消息进行加密。transform(self)
: 这个方法会使用在encrypt
方法中生成的加密映射,把原始句子转变为加密后的句子,并把结果存储在self.replaced_sentence
中。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 个回答
我修改了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
这个解决方案经过了大量的改进。关键在于使用 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!