Triển khai máy Enigma


18

Máy Enigma là một máy mật mã khá phức tạp được người Đức và những người khác sử dụng để mã hóa tin nhắn của họ. Đó là công việc của bạn để thực hiện máy này *.

Bước 1, Xoay

Máy enigma của chúng tôi có 3 khe cho cánh quạt và 5 cánh quạt có sẵn cho mỗi khe này. Mỗi cánh quạt có 26 vị trí khác nhau có thể (từ Ađến Z). Mỗi cánh quạt có một vị trí notch được xác định trước :

Rotor  Notch
------------
1      Q
2      E
3      V
4      J
5      Z

Khi nhấn phím, các bước sau đây xảy ra:

  1. Rôto trong Khe 1 quay
  2. Nếu rôto trong Khe 1 di chuyển qua rãnh của nó, thì nó sẽ quay rôto trong Khe 2.
  3. Nếu rôto trong Khe 2 ở vị trí cao nhất (nhưng không di chuyển đến đó), cả rôto 2 và 3 đều quay một lần.

Nếu chúng ta đang sử dụng rotor 1,3,5 và họ là ở các vị trí P,U,Hsau đó trình tự các vị trí là: P,U,H> Q,U,H> R,V,H>S,W,I

Bước 2, Thay thế

Mỗi cánh quạt thực hiện thay thế ký tự đơn giản. Sau đây là biểu đồ của từng cánh quạt ở Avị trí:

  ABCDEFGHIJKLMNOPQRSTUVWXYZ
  --------------------------
1 EKMFLGDQVZNTOWYHXUSPAIBRCJ
2 AJDKSIRUXBLHWTMCQGZNPYFVOE
3 BDFHJLCPRTXVZNYEIWGAKMUSQO
4 ESOVPZJAYQUIRHXLNFTGKDCMWB
5 VZBRGITYUPSDNHLXAWMJQOFECK
R YRUHQSLDPXNGOKMIEBFZCWVJAT

Rôto 1 ở vị trí T là PAIBRCJEKMFLGDQVZNTOWYHXUS, sẽ thay thế chữ cái Ccho I.

Sau khi ba cánh quạt thực hiện thay thế, phản xạ được nhấn (được liệt kê như Rtrên). Nó thực hiện thay thế riêng của mình, và sau đó phản xạ tín hiệu trở lại thông qua các cánh quạt. Các cánh quạt sau đó thực hiện một sự thay thế ngược theo thứ tự ngược lại.

Phương tiện thay thế ngược lại rằng thay vì Rotor 1 thế chỗ Avới E, nó thay thế EvớiA

Các khe được lấp đầy với các cánh quạt 1,2,3 tất cả trong vị trí A. Bức thư Qđi theo con đường Q>X>V>Mxuyên qua các cánh quạt. Mphản ánh O, sau đó theo con đường ngược lại của O>Z>S>S. Do đó, Ađược thay thế bằng S.

Đầu ra đầu vào

Bạn được thông qua:

  1. Danh sách 3 rôto (dưới dạng số nguyên)
  2. Danh sách 3 vị trí rôto bắt đầu (dưới dạng chữ cái)
  3. Một chuỗi cần được mã hóa.

Bạn có thể giả định rằng đầu vào của bạn sẽ được hình thành tốt và tất cả các ký tự sẽ là chữ in hoa, không có dấu cách.

Bạn phải trả lại chuỗi được mã hóa.

Bạn có thể tùy ý chấp nhận các cánh quạt, rãnh và phản xạ làm đầu vào. Đối với những người không thể lấy 95 byte từ điểm số của họ, như95 = ceil(log2(26 letters ^(26*6 rotors +5 notches))/8 bytes)

Các trường hợp thử nghiệm

Rotor Position Input              Output
4,1,5 H,P,G    AAAAAAAAA          RPWKMBZLN
1,2,3 A,A,A    PROGRAMMINGPUZZLES RTFKHDOVZSXTRMVPFC
1,2,3 A,A,A    RTFKHDOVZSXTRMVPFC PROGRAMMINGPUZZLES
2,5,3 U,L,I    GIBDZNJLGXZ        UNCRACKABLE

Triển khai của tôi có thể được tìm thấy trên Github . Tôi đã thử nghiệm nó, nhưng tôi có thể có lỗi trong quá trình thực hiện (điều đó có nghĩa là các trường hợp thử nghiệm của tôi có khả năng sai).

* Tôi đã cố gắng làm điều này chính xác nhất có thể , nhưng do các biến thể giữa các máy, tôi có thể có một số chi tiết sai. Tuy nhiên, nhiệm vụ của bạn là thực hiện những gì tôi đã mô tả, ngay cả khi tôi không chính xác. Tôi không bao gồm các plugboard cho đơn giản


1
Đây là một triển khai chính xác cho thuật toán mã hóa được sử dụng trong Enigma I, M3 & M4. Tất cả các cài đặt đều có, trình cắm và công tắc Uhr cũng hoạt động: https://github.com/arduinoenigma/ArduinoEnigmaEngineAndUhr Đây là công cụ mã hóa tương tự được sử dụng trong Trình mô phỏng máy Arduino Enigma

Tôi nghĩ rằng tôi hiểu, nhưng nó dường như không hoạt động đúng. Đây là một ý chính giải thích nó gist.github.com/JJ-Atkinson/ddd3896fe10d85b3b584 .
J Atkin

Trong ví dụ đầu tiên bạn đã nói "nếu chúng ta đang sử dụng các rôto 1, 3 và 5" nhưng tôi nghĩ đây sẽ là các rôto 1, 2 và 5 (hoặc bất cứ thứ gì cho lần cuối).
coredump

@coredump Đã sửa lỗi
Nathan Merrill

Là sự hiểu biết của tôi về cách thức hoạt động của cánh quạt vẫn không chính xác?
J Atkin

Câu trả lời:


4

Python 3, 403 byte

Tôi nghĩ rằng điều này là hoạt động chính xác. Các cánh quạt truyền cho nó:

def z(p,o,m,f,g,h):
 O=ord;b=lambda a:a[1:]+a[:1];d=lambda a:chr(a+O('A'));e=lambda a:O(a)-O('A');i=[list(g[i-1])for i in p];j=[f[i-1]for i in p];i=[x[e(y):]+x[:e(y)]for x,y in zip(i,o)];k=[]
 for l in m:
  if i[0][0]==j[0]:i[1]=b(i[1])
  elif i[1][0]==j[1]:i[1]=b(i[1]);i[2]=b(i[2])
  i[0]=b(i[0]);c=l
  for n in i:c=n[e(c)]
  c=h[e(c)]
  for n in reversed(i):c=d(n.index(c))
  k+=[c]
 return''.join(k)

flà notch, glà cánh quạt và hlà gương phản xạ.

Ung dung:

shift = lambda rotor: rotor[1:] + rotor[:1]
letter = lambda num: chr(num + ord('A'))
number = lambda chr: ord(chr) - ord('A')


def encode(rotors, rotorStart, message, defaultRotors, reflector, rotorNotchPositions):
    usedRotors = [list(defaultRotors[i - 1]) for i in rotors]
    notches = [rotorNotchPositions[i - 1] for i in rotors]
    usedRotors = [rotor[number(offset):] + rotor[:number(offset)] for rotor, offset in zip(usedRotors, rotorStart)]

    sub = []

    for char in message:
        # print([''.join(rotor) for rotor in usedRotors])
        if usedRotors[0][0] == notches[0]:
            usedRotors[1] = shift(usedRotors[1])
        elif usedRotors[1][0] == notches[1]:
            usedRotors[1] = shift(usedRotors[1])
            usedRotors[2] = shift(usedRotors[2])

        usedRotors[0] = shift(usedRotors[0])

        c = char
        for rotor in usedRotors:
            c = rotor[number(c)]
        c = reflector[number(c)]
        for rotor in reversed(usedRotors):
            c = letter(rotor.index(c))
        sub += [c]
        print([''.join(rotor) for rotor in usedRotors], char, c, message)

    return ''.join(sub)

rotorNotchPositions = 'QEVJZ'
*defaultRotors, reflector = [
    #ABCDEFGHIJKLMNOPQRSTUVWXYZ#
    "EKMFLGDQVZNTOWYHXUSPAIBRCJ",  # 1
    "AJDKSIRUXBLHWTMCQGZNPYFVOE",  # 2
    "BDFHJLCPRTXVZNYEIWGAKMUSQO",  # 3
    "ESOVPZJAYQUIRHXLNFTGKDCMWB",  # 4
    "VZBRGITYUPSDNHLXAWMJQOFECK",  # 5
    "YRUHQSLDPXNGOKMIEBFZCWVJAT"   # R
]

#             Rotor       Position        Input                 Output
assert encode((4, 1, 5), ('H', 'R', 'G'), 'AAAAAAAAA',
              defaultRotors, reflector, rotorNotchPositions) == 'PXSHJMMHR'
assert encode((1, 2, 3), ('A', 'A', 'A'), 'PROGRAMMINGPUZZLES',
              defaultRotors, reflector, rotorNotchPositions) == 'RTFKHDOCCDAHRJJDFC'
assert encode((1, 2, 3), ('A', 'A', 'A'), 'RTFKHDOVZSXTRMVPFC',
              defaultRotors, reflector, rotorNotchPositions) == 'PROGRAMRXGVGUVFCES'
assert encode((2, 5, 3), ('U', 'L', 'I'), 'GIBDZNJLGXZ',
              defaultRotors, reflector, rotorNotchPositions) == 'UNCRAUPSCTK'

Tôi nghĩ rằng điều này đang hoạt động, nhưng nó tạo ra một đầu ra khác, do những gì (tôi nghĩ) là một lỗi trong hàm tham chiếu.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.