Terapkan Mesin Enigma


18

Mesin Enigma adalah mesin sandi yang cukup rumit yang digunakan oleh orang Jerman dan lainnya untuk mengenkripsi pesan mereka. Adalah tugas Anda untuk mengimplementasikan mesin ini *.

Langkah 1, Rotasi

Mesin enigma kami memiliki 3 slot untuk rotor, dan 5 rotor yang tersedia untuk masing-masing slot ini. Setiap rotor memiliki 26 posisi yang berbeda (dari Ake Z). Setiap rotor memiliki posisi takik yang telah ditentukan :

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

Pada penekanan tombol, langkah-langkah berikut terjadi:

  1. Rotor di Slot 1 berputar
  2. Jika rotor di Slot 1 bergerak melewati takiknya, maka rotor diputar di Slot 2.
  3. Jika rotor di Slot 2 berada di tingkatnya (tetapi tidak hanya bergerak di sana), rotor 2 dan 3 berputar sekali.

Jika kita menggunakan rotor 1,3,5 dan mereka berada di posisi P,U,Hmaka urutan posisi adalah: P,U,H> Q,U,H> R,V,H>S,W,I

Langkah 2, Substitusi

Setiap rotor melakukan penggantian karakter sederhana. Berikut ini adalah bagan dari masing-masing rotor pada Aposisi:

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

Rotor 1 pada posisi T adalah PAIBRCJEKMFLGDQVZNTOWYHXUS, yang akan menggantikan huruf Cuntuk I.

Setelah ketiga rotor melakukan pergantian, reflektor dipukul (terdaftar seperti di Ratas). Ia melakukan substitusi sendiri, dan kemudian memantulkan kembali sinyal melalui rotor. Rotor kemudian melakukan penggantian terbalik dengan urutan terbalik.

Substitusi terbalik berarti bahwa alih-alih Rotor 1 menggantikan Adengan E, itu menggantikan EdenganA

Slot diisi dengan rotor 1,2,3 semuanya ada di posisinya A. Surat itu Qmengikuti jalan Q>X>V>Mmelalui rotor. Mmencerminkan O, yang kemudian mengikuti jalur kebalikan dari O>Z>S>S. Oleh karena itu, Adiganti dengan S.

Input output

Anda lulus:

  1. Daftar 3 rotor (sebagai bilangan bulat)
  2. Daftar 3 posisi awal rotor (sebagai huruf)
  3. Sebuah string yang perlu dienkripsi.

Anda dapat mengasumsikan bahwa input Anda akan terbentuk dengan baik, dan semua karakter akan menjadi huruf besar, tanpa spasi.

Anda harus mengembalikan string terenkripsi.

Anda secara opsional dapat menerima rotor, takik, dan reflektor sebagai input. Bagi mereka yang tidak dapat melepas 95 byte dari skor mereka, sebagai95 = ceil(log2(26 letters ^(26*6 rotors +5 notches))/8 bytes)

Uji kasus

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

Implementasi saya dapat ditemukan di Github . Saya telah mengujinya, tetapi saya mungkin memiliki bug dalam implementasi saya (yang berarti bahwa kasus pengujian saya kemungkinan salah).

* Saya sudah mencoba membuat ini seakurat mungkin , tetapi karena variasi antar mesin, saya mungkin memiliki beberapa detail yang salah. Namun, tugas Anda adalah mengimplementasikan apa yang telah saya jelaskan, bahkan jika saya tidak akurat. Saya tidak termasuk plugboard untuk kesederhanaan


1
Ini adalah implementasi yang benar untuk algoritma enkripsi yang digunakan dalam Enigma I, M3 & M4. Semua pengaturan hadir, plugboard dan sakelar Uhr juga berfungsi: https://github.com/arduinoenigma/ArduinoEnigmaEngineAndUhr Ini adalah mesin enkripsi yang sama yang digunakan dalam Arduino Enigma Machine Simulator

Saya pikir saya mengerti, tetapi sepertinya tidak berhasil. Berikut adalah intisari yang menjelaskannya gist.github.com/JJ-Atkinson/ddd3896fe10d85b3b584 .
J Atkin

Dalam contoh pertama Anda mengatakan "jika kita menggunakan rotor 1, 3 dan 5" tapi saya pikir ini akan menjadi rotor 1, 2 dan 5 (atau apa pun untuk yang terakhir).
coredump

@coredump Tetap
Nathan Merrill

Apakah pemahaman saya tentang cara kerja rotor masih salah?
J Atkin

Jawaban:


4

Python 3, 403 byte

Saya pikir ini berfungsi dengan benar. Rotor diteruskan ke sana:

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)

fadalah takik, gadalah rotor dan hreflektor.

Tidak Disatukan:

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'

Saya pikir ini berfungsi, tetapi menghasilkan output yang berbeda, karena apa (saya pikir) adalah bug dalam referensi impl.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.