Enigma Makinesi'ni uygulayın


18

Enigma makinesi, Almanlar ve diğerleri tarafından mesajlarını şifrelemek için kullanılan oldukça karmaşık bir şifreleme makinesidir. Bu makineyi uygulamak sizin işinizdir *.

Adım 1, Döndürme

Enigma makinemizde rotorlar için 3 yuva ve bu yuvaların her biri için 5 mevcut rotor vardır. Her bir rotor (26 olası farklı pozisyonlara sahip Aiçin Z). Her rotorun önceden tanımlanmış bir çentik konumu vardır :

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

Tuşa basıldığında aşağıdaki adımlar gerçekleşir:

  1. Yuva 1'deki rotor döner
  2. Yuva 1'deki rotor çentiğini geçtikten sonra rotoru Yuva 2'de döndürür.
  3. Yuva 2'deki rotor çentikteyse (ancak sadece oraya hareket etmediyse), hem rotor 2 hem de 3 bir kez döner.

Biz rotorlar 1,3,5 kullanılmakta ve bu konumlarda ise P,U,Ho zaman pozisyon sekansı: P,U,H> Q,U,H> R,V,H>S,W,I

2. Adım, Değiştirme

Rotorların her biri basit bir karakter ikamesi yapar. Aşağıdaki, Akonumdaki rotorların her birinin bir grafiğidir :

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

T konumundaki Rotor 1, PAIBRCJEKMFLGDQVZNTOWYHXUSyerine mektubu Ckoyacaktır I.

Üç rotor yerine geçtikten sonra reflektör vurulur ( Ryukarıdaki gibi listelenir ). Kendi yerine koyma işlemini gerçekleştirir ve daha sonra sinyali rotorlara geri yansıtır. Rotorlar daha sonra ters sırada bir ters ikame gerçekleştirir.

Bunun yerine 1 ikame Rotor Ters ikame araçları Aile E, ikame ettiği EileA

Yuvalar, hepsi yerinde 1,2,3 rotor ile doldurulur A. Mektup , rotorlar Qarasındaki yolu izler Q>X>V>M. Myansıtır O, sonra ters yolunu izler O>Z>S>S. Bu nedenle, Aile değiştirilir S.

Giriş çıkış

Siz geçtiniz:

  1. 3 rotor listesi (tamsayı olarak)
  2. 3 başlangıç ​​rotor konumunun listesi (harf olarak)
  3. Şifrelenmesi gereken bir dize.

Girişinizin iyi oluşturulacağını ve tüm karakterlerin büyük harf olacağını, boşluk olmayacağını varsayabilirsiniz.

Şifrelenmiş dizeyi döndürmelisiniz.

İsteğe bağlı olarak rotorları, çentikleri ve reflektörleri giriş olarak kabul edebilirsiniz. Puanlarından 95 bayt çıkaramayanlar için,95 = ceil(log2(26 letters ^(26*6 rotors +5 notches))/8 bytes)

Test senaryoları

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

Uygulamam Github'da bulunabilir . Test ettim, ancak uygulamamda hatalar olabilir (bu benim test durumlarımın muhtemelen yanlış olduğu anlamına gelir).

* Bunu olabildiğince doğru yapmaya çalıştım , ancak makineler arasındaki farklılıklar nedeniyle bazı ayrıntılar yanlış olabilir. Ancak göreviniz yanlış olsam bile tarif ettiğim şeyi uygulamaktır. Basitlik için panoya dahil etmiyorum


1
Bu, Enigma I, M3 ve M4'te kullanılan şifreleme algoritması için doğru bir uygulamadır. Tüm ayarlar mevcut, anakart ve Uhr anahtarı da çalışıyor: https://github.com/arduinoenigma/ArduinoEnigmaEngineAndUhr Bu, Arduino Enigma Machine Simulator'da

Sanırım anlıyorum, ama işe yaramıyor gibi görünüyor. İşte gist.github.com/JJ-Atkinson/ddd3896fe10d85b3b584 açıklayan bir öz .
J Atkin

İlk örnekte "1, 3 ve 5 rotorlarını kullanıyorsak" dediniz, ancak bence bu 1, 2 ve 5 numaralı rotorlar (ya da sonuncusu için ne olursa olsun).
coredump

@coredump Sabit
Nathan Merrill

Rotorların nasıl çalıştığı konusundaki anlayışım hala yanlış mı?
J Atkin

Yanıtlar:


4

Python 3, 403 bayt

Bence bu doğru çalışıyor. Rotorlar ona geçti:

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)

fçentik, grotorlar ve hreflektördür.

Ungolfed:

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'

Bence bu işe yarıyor, ama referans impl bir hata ne (bence) nedeniyle farklı bir çıktı üretir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.