Enigma comes from Greek and is interpreted in English as "a mystery, an incomprehensible thing".
-- Excerpt from Ele Laboratory
As we know, enigma machine is an important information encryption machine of the German army in World War II, which has many characteristics.
First of all, it is an all-in-one encryption and decryption machine
Secondly, it is exclusive. Although different ciphertexts may be obtained by inputting the same plaintext many times, plaintext a can never be encrypted as itself. This perfect concealment of the nature of the plaintext itself was caused by the reflector, but it was finally used by Turing to give a fatal blow to the enigma machine.
Enigma machine has many different models, such as 3-wheel type, 5-wheel type, 5-wheel type, 3-wheel type and so on. I repeat the program of three wheel Enigma machine. What needs to be explained is that because the essence of enigma is the rotor and the reflector, the code also repeats this process, and the wiring board is omitted. After all, the power of Enigma machine is that it is so crazy that it almost abnormal that it can almost "change the table word by word", and the terminal block is only a simple letter replacement, which is nothing new in itself.
Don't say much, just go to the code: (see the end of the text for some instructions)
# -*- coding: utf-8 -*- """ Created on Tue Jan 4 09:40:42 2022 @author: burger """ from numpy import random import numpy as np import time arr = np.array(['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']) #Enter a batch number num = input('Please enter the name you want to use enigma Machine batch number XXX-XXX-XXX(Example: 123-456-789)\n') filename = 'enigma_code_book.txt' with open(filename) as file_object: context = file_object.read() if num in context: number = context.find(num) arr_a=context[(number+12):(number+38)] #Runner 1 arr_b=context[(number+39):(number+65)] #Runner 2 arr_c=context[(number+66):(number+92)] #Runner 3 arr_d=context[(number+93):(number+119)] #Reflector else: arr_a=random.permutation(arr) arr_b=random.permutation(arr) arr_c=random.permutation(arr) arr_d=random.permutation(arr) with open(filename,'a') as file_object: str_1='\n' str_1=str_1+num str_1+=' ' for i in range(len(arr_a)): str_1+=arr_a[i] str_1+=' ' for i in range(len(arr_b)): str_1+=arr_b[i] str_1+=' ' for i in range(len(arr_c)): str_1+=arr_c[i] str_1+=' ' for i in range(len(arr_d)): str_1+=arr_d[i] str_1+=' ' file_object.write(str_1) zzwz=input('Please enter the initial rotor position(The specification is three English letters with two English commas in the middle)\n eg: a,b,c\n')#zzwz is the rotor position zz_1=list(zzwz)[0] zz_2=list(zzwz)[2] zz_3=list(zzwz)[4] num_zz_1=ord(zz_1)-97 num_zz_2=ord(zz_2)-97 num_zz_3=ord(zz_3)-97 def main(): global num_zz_1 global num_zz_2 global num_zz_3 text=input('Please enter the encrypted content\n') for n in range(len(text)): string=list(text)[n] print(zhuanhuan(string),end='') num_zz_1+=1 if num_zz_1 == 26: num_zz_1 = 0 num_zz_2+=1 if num_zz_2 == 26: num_zz_2=0 num_zz_3+=1 if num_zz_3 == 26: num_zz_3 = 0 def zhuanhuan(letter): #Runner a #There are 26 contacts on the right #Random connection mode for generating round a a_1_1=False a_1_2=False a_1_3=False a_1_4=False a_1_5=False a_1_6=False a_1_7=False a_1_8=False a_1_9=False a_1_10=False a_1_11=False a_1_12=False a_1_13=False a_1_14=False a_1_15=False a_1_16=False a_1_17=False a_1_18=False a_1_19=False a_1_20=False a_1_21=False a_1_22=False a_1_23=False a_1_24=False a_1_25=False a_1_26=False if letter == 'a': a_1_1 = True if letter == 'b': a_1_2 = True elif letter == 'c': a_1_3 = True elif letter == 'd': a_1_4 = True elif letter == 'e': a_1_5 = True elif letter == 'f': a_1_6 = True elif letter == 'g': a_1_7 = True elif letter == 'h': a_1_8 = True elif letter == 'i': a_1_9 = True elif letter == 'j': a_1_10 = True elif letter == 'k': a_1_11 = True elif letter == 'l': a_1_12 = True elif letter == 'm': a_1_13 = True elif letter == 'n': a_1_14 = True elif letter == 'o': a_1_15 = True elif letter == 'p': a_1_16 = True elif letter == 'q': a_1_17 = True elif letter == 'r': a_1_18 = True elif letter == 's': a_1_19 = True elif letter == 't': a_1_20 = True elif letter == 'u': a_1_21 = True elif letter == 'v': a_1_22 = True elif letter == 'w': a_1_23 = True elif letter == 'x': a_1_24 = True elif letter == 'y': a_1_25 = True elif letter == 'z': a_1_26 = True a_1_first=[a_1_1,a_1_2,a_1_3,a_1_4,a_1_5,a_1_6,a_1_7,a_1_8,a_1_9,a_1_10,a_1_11,a_1_12,a_1_13,a_1_14,a_1_15,a_1_16,a_1_17,a_1_18,a_1_19,a_1_20,a_1_21,a_1_22,a_1_23,a_1_24,a_1_25,a_1_26] # print(a_1_first) a_1=[False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False] for i in range(26): global num_zz_1 a_1[i]=a_1_first[(num_zz_1-26)+i] # print(a_1) #There are 26 contacts on the left side a_2_1=False a_2_2=False a_2_3=False a_2_4=False a_2_5=False a_2_6=False a_2_7=False a_2_8=False a_2_9=False a_2_10=False a_2_11=False a_2_12=False a_2_13=False a_2_14=False a_2_15=False a_2_16=False a_2_17=False a_2_18=False a_2_19=False a_2_20=False a_2_21=False a_2_22=False a_2_23=False a_2_24=False a_2_25=False a_2_26=False a_2=[a_2_1,a_2_2,a_2_3,a_2_4,a_2_5,a_2_6,a_2_7,a_2_8,a_2_9,a_2_10,a_2_11,a_2_12,a_2_13,a_2_14,a_2_15,a_2_16,a_2_17,a_2_18,a_2_19,a_2_20,a_2_21,a_2_22,a_2_23,a_2_24,a_2_25,a_2_26] #Build the left-right correspondence of runner a for i in range(26): a_2[i]=a_1[ord(arr_a[i])-97] # print(a_2) #At this time, the modeling of runner a is successful #Runner b #There are 26 contacts on the right b_1_1=False b_1_2=False b_1_3=False b_1_4=False b_1_5=False b_1_6=False b_1_7=False b_1_8=False b_1_9=False b_1_10=False b_1_11=False b_1_12=False b_1_13=False b_1_14=False b_1_15=False b_1_16=False b_1_17=False b_1_18=False b_1_19=False b_1_20=False b_1_21=False b_1_22=False b_1_23=False b_1_24=False b_1_25=False b_1_26=False b_1=[b_1_1,b_1_2,b_1_3,b_1_4,b_1_5,b_1_6,b_1_7,b_1_8,b_1_9,b_1_10,b_1_11,b_1_12,b_1_13,b_1_14,b_1_15,b_1_16,b_1_17,b_1_18,b_1_19,b_1_20,b_1_21,b_1_22,b_1_23,b_1_24,b_1_25,b_1_26] #Wheel a to wheel b for i in range(26): global num_zz_2 b_1[i]=a_2[((num_zz_2)-26)+i] # print(b_1) #There are 26 contacts on the left b_2_1=False b_2_2=False b_2_3=False b_2_4=False b_2_5=False b_2_6=False b_2_7=False b_2_8=False b_2_9=False b_2_10=False b_2_11=False b_2_12=False b_2_13=False b_2_14=False b_2_15=False b_2_16=False b_2_17=False b_2_18=False b_2_19=False b_2_20=False b_2_21=False b_2_22=False b_2_23=False b_2_24=False b_2_25=False b_2_26=False b_2=[b_2_1,b_2_2,b_2_3,b_2_4,b_2_5,b_2_6,b_2_7,b_2_8,b_2_9,b_2_10,b_2_11,b_2_12,b_2_13,b_2_14,b_2_15,b_2_16,b_2_17,b_2_18,b_2_19,b_2_20,b_2_21,b_2_22,b_2_23,b_2_24,b_2_25,b_2_26] #Build the left-right correspondence of runner b for i in range(26): b_2[i]=b_1[ord(arr_b[i])-97] # print(b_2) #At this time, the modeling of runner b is successful #Runner c #There are 26 contacts on the right c_1_1=False c_1_2=False c_1_3=False c_1_4=False c_1_5=False c_1_6=False c_1_7=False c_1_8=False c_1_9=False c_1_10=False c_1_11=False c_1_12=False c_1_13=False c_1_14=False c_1_15=False c_1_16=False c_1_17=False c_1_18=False c_1_19=False c_1_20=False c_1_21=False c_1_22=False c_1_23=False c_1_24=False c_1_25=False c_1_26=False c_1=[c_1_1,c_1_2,c_1_3,c_1_4,c_1_5,c_1_6,c_1_7,c_1_8,c_1_9,c_1_10,c_1_11,c_1_12,c_1_13,c_1_14,c_1_15,c_1_16,c_1_17,c_1_18,c_1_19,c_1_20,c_1_21,c_1_22,c_1_23,c_1_24,c_1_25,c_1_26] #Wheel b to wheel c for i in range(26): global num_zz_3 c_1[i]=b_2[((num_zz_3)-26)+i] # print(c_1) #There are 26 contacts on the left c_2_1=False c_2_2=False c_2_3=False c_2_4=False c_2_5=False c_2_6=False c_2_7=False c_2_8=False c_2_9=False c_2_10=False c_2_11=False c_2_12=False c_2_13=False c_2_14=False c_2_15=False c_2_16=False c_2_17=False c_2_18=False c_2_19=False c_2_20=False c_2_21=False c_2_22=False c_2_23=False c_2_24=False c_2_25=False c_2_26=False c_2=[c_2_1,c_2_2,c_2_3,c_2_4,c_2_5,c_2_6,c_2_7,c_2_8,c_2_9,c_2_10,c_2_11,c_2_12,c_2_13,c_2_14,c_2_15,c_2_16,c_2_17,c_2_18,c_2_19,c_2_20,c_2_21,c_2_22,c_2_23,c_2_24,c_2_25,c_2_26] #Build the left-right correspondence of runner c for i in range(26): c_2[i]=c_1[ord(arr_c[i])-97] # print(c_2) #At this time, the modeling of runner c is successful #c runner reflector for i in range(0,26,2): c_2[ord(arr_d[i])-97],c_2[ord(arr_d[i+1])-97]=c_2[ord(arr_d[i+1])-97],c_2[ord(arr_d[i])-97] #Back propagation arr_c_2=[] arr_b_2=[] arr_a_2=[] arr_c_1=[] arr_b_1=[] arr_a_1=[] for i in range(26): arr_c_2.append(ord(arr_c[i])-97) arr_b_2.append(ord(arr_b[i])-97) arr_a_2.append(ord(arr_a[i])-97) arr_c_0=sorted(arr_c_2) arr_b_0=sorted(arr_b_2) arr_a_0=sorted(arr_a_2) for i in range(26): arr_c_1.append(arr_c_2.index(arr_c_0[i])) arr_b_1.append(arr_b_2.index(arr_c_0[i])) arr_a_1.append(arr_a_2.index(arr_c_0[i])) #Runner c back propagation c_3_1=False c_3_2=False c_3_3=False c_3_4=False c_3_5=False c_3_6=False c_3_7=False c_3_8=False c_3_9=False c_3_10=False c_3_11=False c_3_12=False c_3_13=False c_3_14=False c_3_15=False c_3_16=False c_3_17=False c_3_18=False c_3_19=False c_3_20=False c_3_21=False c_3_22=False c_3_23=False c_3_24=False c_3_25=False c_3_26=False c_3=[c_3_1,c_3_2,c_3_3,c_3_4,c_3_5,c_3_6,c_3_7,c_3_8,c_3_9,c_3_10,c_3_11,c_3_12,c_3_13,c_3_14,c_3_15,c_3_16,c_3_17,c_3_18,c_3_19,c_3_20,c_3_21,c_3_22,c_3_23,c_3_24,c_3_25,c_3_26] for i in range(26): c_3[i]=c_2[arr_c_1[i]] # print(c_3) #Wheel c to wheel b b_3_1=False b_3_2=False b_3_3=False b_3_4=False b_3_5=False b_3_6=False b_3_7=False b_3_8=False b_3_9=False b_3_10=False b_3_11=False b_3_12=False b_3_13=False b_3_14=False b_3_15=False b_3_16=False b_3_17=False b_3_18=False b_3_19=False b_3_20=False b_3_21=False b_3_22=False b_3_23=False b_3_24=False b_3_25=False b_3_26=False b_3=[b_3_1,b_3_2,b_3_3,b_3_4,b_3_5,b_3_6,b_3_7,b_3_8,b_3_9,b_3_10,b_3_11,b_3_12,b_3_13,b_3_14,b_3_15,b_3_16,b_3_17,b_3_18,b_3_19,b_3_20,b_3_21,b_3_22,b_3_23,b_3_24,b_3_25,b_3_26] for i in range(26): # global num_zz_3 b_3[i]=c_3[-(num_zz_3)+i]#There are 26 contacts on the left # print(b_3) #Runner b back propagation b_4_1=False b_4_2=False b_4_3=False b_4_4=False b_4_5=False b_4_6=False b_4_7=False b_4_8=False b_4_9=False b_4_10=False b_4_11=False b_4_12=False b_4_13=False b_4_14=False b_4_15=False b_4_16=False b_4_17=False b_4_18=False b_4_19=False b_4_20=False b_4_21=False b_4_22=False b_4_23=False b_4_24=False b_4_25=False b_4_26=False b_4=[b_4_1,b_4_2,b_4_3,b_4_4,b_4_5,b_4_6,b_4_7,b_4_8,b_4_9,b_4_10,b_4_11,b_4_12,b_4_13,b_4_14,b_4_15,b_4_16,b_4_17,b_4_18,b_4_19,b_4_20,b_4_21,b_4_22,b_4_23,b_4_24,b_4_25,b_4_26] for i in range(26): b_4[i]=b_3[arr_b_1[i]] # print(b_4) #Wheel b to wheel a a_3_1=False a_3_2=False a_3_3=False a_3_4=False a_3_5=False a_3_6=False a_3_7=False a_3_8=False a_3_9=False a_3_10=False a_3_11=False a_3_12=False a_3_13=False a_3_14=False a_3_15=False a_3_16=False a_3_17=False a_3_18=False a_3_19=False a_3_20=False a_3_21=False a_3_22=False a_3_23=False a_3_24=False a_3_25=False a_3_26=False a_3=[a_3_1,a_3_2,a_3_3,a_3_4,a_3_5,a_3_6,a_3_7,a_3_8,a_3_9,a_3_10,a_3_11,a_3_12,a_3_13,a_3_14,a_3_15,a_3_16,a_3_17,a_3_18,a_3_19,a_3_20,a_3_21,a_3_22,a_3_23,a_3_24,a_3_25,a_3_26] for i in range(26): # global num_zz_2 a_3[i]=b_4[-(num_zz_2)+i]#There are 26 contacts on the left # print(a_3) #Runner a back propagation a_4_1=False a_4_2=False a_4_3=False a_4_4=False a_4_5=False a_4_6=False a_4_7=False a_4_8=False a_4_9=False a_4_10=False a_4_11=False a_4_12=False a_4_13=False a_4_14=False a_4_15=False a_4_16=False a_4_17=False a_4_18=False a_4_19=False a_4_20=False a_4_21=False a_4_22=False a_4_23=False a_4_24=False a_4_25=False a_4_26=False a_4=[a_4_1,a_4_2,a_4_3,a_4_4,a_4_5,a_4_6,a_4_7,a_4_8,a_4_9,a_4_10,a_4_11,a_4_12,a_4_13,a_4_14,a_4_15,a_4_16,a_4_17,a_4_18,a_4_19,a_4_20,a_4_21,a_4_22,a_4_23,a_4_24,a_4_25,a_4_26] for i in range(26): a_4[i]=a_3[arr_a_1[i]] # print(a_4) #Round a return z_3_1=False z_3_2=False z_3_3=False z_3_4=False z_3_5=False z_3_6=False z_3_7=False z_3_8=False z_3_9=False z_3_10=False z_3_11=False z_3_12=False z_3_13=False z_3_14=False z_3_15=False z_3_16=False z_3_17=False z_3_18=False z_3_19=False z_3_20=False z_3_21=False z_3_22=False z_3_23=False z_3_24=False z_3_25=False z_3_26=False z_3=[z_3_1,z_3_2,z_3_3,z_3_4,z_3_5,z_3_6,z_3_7,z_3_8,z_3_9,z_3_10,z_3_11,z_3_12,z_3_13,z_3_14,z_3_15,z_3_16,z_3_17,z_3_18,z_3_19,z_3_20,z_3_21,z_3_22,z_3_23,z_3_24,z_3_25,z_3_26] for i in range(26): # global num_zz_1 z_3[i]=a_4[-(num_zz_1)+i] # print(z_3) for i in range(26): if z_3[i]==True: return(chr(i+97)) if __name__ == '__main__': main()
Briefly explain the code. The general idea is to use a boolean type list to represent the power on or power off of each group of 26 contacts. In the process of reproduction, Turing used an idea when cracking the Enigma machine: place the two enigma machines with completely symmetrical wiring side by side. Among them, the processing method of True transfer and the simulation method of reflector are my more satisfactory places.
In the process of reflection, there is a more interesting thing. Above:
Take four contacts as an example. In forward propagation, we take the left contact as the benchmark and read the serial number of the right contact as 3412. In reverse propagation, we take the right contact as the benchmark and read the serial number of the left contact as 2413. How to build 2413 according to 3412 is a key. A friend of the author provided a good idea. Assuming 3412 is stored in list a, list a is sorted from small to large and stored in list B. Record the subscript of each element in List B in list a in list C, and list C is what we want.
Then follow the example of forward propagation and back propagation.
Let's talk about the use of the code. Create a file named enigma in the same directory of the source code_ code_ book. Txt file, which is used to roughly store the model of Enigma machine, the wiring mode of three runners and one reflector.
Click the operation code and randomly input the Enigma machine batch number composed of three groups of three Arabic numerals, such as 123-456-789. Click enter. At this time, the program will automatically generate the wiring method of this batch number Enigma machine. If this batch of Enigma machine has been used, it shall be used in enigma_ code_ Automatically find the required wiring mode in book.
Then input the initial runner position, which shall be three lowercase English letters separated by commas, such as a, B and C. Press enter, and then enter the plaintext content to be encrypted. Press enter to generate the ciphertext.
If you want to decrypt, you need to enter the same batch number, the same initial rotor position, and enter the ciphertext to decrypt the plaintext.
It should be noted that, following the enigma machine in history, only 26 lowercase English letters are encrypted here, without encryption of numbers, uppercase English letters and punctuation marks. Because these are just some building blocks based on different application requirements. The author also considers that if you want to encrypt Chinese, you can first expand the enigma machine into capital letters and Arabic numerals, and then combine the value of base64.
Let's stop here for the time being. The newcomer writes a blog for the first time. I hope you like it.