从上面明文到密文的转换可以得出这样的规律 密文->明文 :
| A | B | C | D | E | F |
| +1 | -1 | +3 | -1 | 0 | -2 |
每次rotor旋转一格 则等价于
| A | B | C | D | E | F |
| -2 | +1 | -1 | +3 | -1 | 0 |
此时C->B 同理rotor再旋转一次 有
| A | B | C | D | E | F |
| 0 | -2 | +1 | -1 | +3 | -1 |
此时E->B 都转换成小写就是bbb
当有三个rotor时,第一个转完一圈第二个转一个,第二个转完一圈第三个转一个
因此对测试数据
6
BADFEC
ABCDEF
ABCDEF
1
ACE
有
| A | B | C | D | E | F |
| +1 | -1 | +3 | -1 | 0 | -2 |
| 0 | 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 0 | 0 | 0 | 0 |
解的时候反过来从最后一个rotor开始 :A+0->A+0->A+1=B,rotor1旋转 ,C+0->C+0->C-1=B,rotor1旋转,E+0->E+0->E+3=B
有多组 Enigma 输出时除第一组数据不能有空行,其他组之间有空行
下面代码的核心部分也就是4-17行
//transform 用于得到密文到明文的转换关系 按照字典顺序从小到大
//riddle 使用rotor对应的解密表#include <stdio.h>
#include <string.h>
#include <ctype.h>
void transform(char r[],int ro[],int m)
{
int i;
for(i = 0;i<m;i++)
{
ro[r[i]-'A'] = ('A'+i)-r[i];
}
}
char riddle (char code,int rotor[],int m,int index)
{
int i = code-'A'-index <0? (m+(code-'A'-index)):code-'A'-index;//例如密文B的转换关系在 rotor[1-index]
int x = rotor[i]+code-'A'<0?(m+(rotor[i]+code-'A')):rotor[i]+code-'A';
return x%m+'A';
}
int main(int argc, char *argv[])
{
int index_1,index_2,index_3,m,n,i,cases;
int rotor_1[26],rotor_2[26],rotor_3[26];
char rotor[26],code;
cases = 0;
while(scanf("%d",&m)&&m!=0)
{
memset(rotor,'\0',sizeof(rotor));
scanf("%s",rotor);
transform(rotor,rotor_1,m);
scanf("%s",rotor);
transform(rotor,rotor_2,m);
scanf("%s",rotor);
transform(rotor,rotor_3,m);
scanf("%d",&n);
getchar();
if(cases++) printf("\n");
printf("Enigma %d:\n",cases);
for(i = 0;i<n;i++)
{
index_1 = index_2 = index_3 = 0;
while(scanf("%c",&code)&&code!='\n')
{
printf("%c",tolower(riddle(riddle(riddle(code,rotor_3,m,index_3),rotor_2,m,index_2),rotor_1,m,index_1)));
index_1++;//偏移量,相对于移动数组
if(index_1==m){index_1 = 0;index_2++;}
if(index_2==m){index_2 = 0;index_3++;}
if(index_3==m) index_3 = 0;
}
printf("\n");
}
}
return 0;
}
本文介绍了一种基于Enigma机的加密算法,并详细解释了其背后的转换规律及实现方式。通过三个转子的不同旋转状态,实现了密文到明文的转换过程。文章还提供了一个具体的解密示例,并给出了C语言实现的代码。
682

被折叠的 条评论
为什么被折叠?



