实施谜机


18

谜机是德国人和其他人用来加密其消息的相当复杂的密码机。实施此机器是您的工作*。

步骤1,旋转

我们的enigma机器有3个转子槽,每个槽有5个可用转子。每个转子都有26个不同的可能位置(从AZ)。每个转子都有一个预定的缺口位置

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

按键时会发生以下步骤:

  1. 插槽1中的转子旋转
  2. 如果插槽1中的转子经过其槽口,则它将旋转插槽2中的转子。
  3. 如果插槽2中的转子在其槽口中(但不只是在那里移动),则转子2和3都会旋转一次。

如果我们使用转子1,3,5和他们中的位置P,U,H,然后位置的顺序是:P,U,H> Q,U,H> R,V,H>S,W,I

步骤2,替代

每个转子执行简单的字符替换。下图是该A位置的每个转子的图表:

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

转子1在位置T is处PAIBRCJEKMFLGDQVZNTOWYHXUS,它将用字母C代替I

在三个转子进行替换后,反射器受到撞击(如上R所列)。它执行自己的替换,然后通过转子将信号反射回去。然后,转子以相反的顺序执行反向替换。

的是,代替转子1代反向替换装置AE,它可以代替EA

插槽中的转子1,2,3均已安装到位A。该字母Q沿Q>X>V>M通过转子的路径移动。 M反映到O,然后遵循的反向路径O>Z>S>S。因此,A用代替S

输入输出

您通过了:

  1. 3个转子的列表(整数)
  2. 3个起始转子位置的列表(以字母表示)
  3. 需要加密的字符串。

您可以假设输入格式正确,所有字符均为大写字母,没有空格。

您必须返回加密的字符串。

您可以选择接受转子,槽口和反射器作为输入。对于那些不能从他们的分数中取出95个字节的用户,例如95 = ceil(log2(26 letters ^(26*6 rotors +5 notches))/8 bytes)

测试用例

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

我的实现可以在Github上找到。我已经测试过了,但是我的实现中可能存在错误(这意味着我的测试用例可能是错误的)。

*我试图使此尽可能准确,但是由于机器之间的差异,我可能有些细节错误。但是,您的任务是执行我所描述的内容,即使我不准确。为了简单起见,我不包括该插件板


1
这是Enigma I,M3和M4中使用的加密算法的正确实现。所有设置均已存在,插件板和Uhr开关也正常工作:https : //github.com/arduinoenigma/ArduinoEnigmaEngineAndUhr这与Arduino Enigma Machine Simulator中

我想我了解,但这似乎行不通。这是一个解释它的要点gist.github.com/JJ-Atkinson/ddd3896fe10d85b3b584
J Atkin

在第一个示例中,您说过“如果我们使用转子1、3和5”,但是我认为这将是转子1、2和5(或者最后一个)。
coredump

@coredump固定
内森·梅里尔

我对转子如何工作的理解仍然不正确吗?
J Atkin

Answers:


4

Python 3,403个字节

我认为这工作正常。转子通过了:

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是缺口,g是转子,h是反射镜。

取消高尔夫:

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'

我认为这可行,但是由于参考隐含的错误(我认为),因此产生了不同的输出。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.