# 导入所需的库 from pycipher import SimpleSubstitution as SimpleSub import random import re from ngram_score import ngram_score import proability import gradio as gr def decrypt_text_internal(ciphertext): fitness = ngram_score('quadgrams.txt') ctext = re.sub('[^A-Z]', '', ciphertext.upper()) maxkey = list('ABCDEFGHIJKLMNOPQRSTUVWXYZ') maxscore = -99e9 parentscore, parentkey = maxscore, maxkey[:] i = 0 # Limit iterations to prevent infinite loops in a web server environment while i < 1000: i = i + 1 random.shuffle(parentkey) deciphered = SimpleSub(parentkey).decipher(ctext) parentscore = fitness.score(deciphered) count = 0 while count < 1000: a = random.randint(0, 25) b = random.randint(0, 25) child = parentkey[:] child[a], child[b] = child[b], child[a] deciphered = SimpleSub(child).decipher(ctext) score = fitness.score(deciphered) if score > parentscore: parentscore = score parentkey = child[:] count = 0 count = count + 1 if parentscore > maxscore: maxscore, maxkey = parentscore, parentkey[:] ss = SimpleSub(maxkey) plaintext = ss.decipher(ctext) plaintext1 = add_punctuation_and_spaces(ciphertext, plaintext) # In a web context, we return the first good result. # The original loop was infinite, which is not suitable for a server. return plaintext1 # Fallback if no good solution is found within the iteration limit ss = SimpleSub(maxkey) plaintext = ss.decipher(ctext) return add_punctuation_and_spaces(ciphertext, plaintext) def output(string1, dic, string2): modified_string1 = list(string1) modified_string2 = list(string2) for i in range(len(string1)): if modified_string1[i] in dic and modified_string2[i] != ' ': modified_string2[i] = dic[modified_string1[i]] modified_string2 = ''.join(modified_string2) return modified_string2 def add_punctuation_and_spaces(ciphertext, plaintext): result = "" j = 0 for i in range(len(ciphertext)): if not ciphertext[i].isalpha(): result += ciphertext[i] else: if ciphertext[i].islower(): result += plaintext[j].lower() else: # The original code had a bug here, always making it lowercase. # This is a guess at the intended behavior. result += plaintext[j] j += 1 return result def decrypt_interface(ciphertext, key): """ This is the main function that will be exposed through the Gradio interface. """ if not ciphertext: return "Please enter some ciphertext." plaintext = decrypt_text_internal(ciphertext) if key: try: key_dic = proability.read_key(key) plaintext = output(ciphertext, key_dic, plaintext) except Exception as e: return f"Error processing key: {e}. Please check the key format (e.g., a=B c=D)." return plaintext # Create the Gradio interface iface = gr.Interface( fn=decrypt_interface, inputs=[ gr.Textbox(lines=10, label="Ciphertext", placeholder="Enter the text to decrypt..."), gr.Textbox(lines=2, label="Known Key Mappings (Optional)", placeholder="e.g., a=B c=D") ], outputs=gr.Textbox(lines=10, label="Plaintext"), title="Simple Substitution Cipher Decryptor", description="An automatic decryption tool for simple substitution ciphers. You can optionally provide known letter mappings to improve accuracy." ) # Launch the app if __name__ == "__main__": iface.launch(server_name="127.0.0.1", server_port=7860)