目前我正在创建我自己的enigma版本作为一个小项目,但如果你了解谜机是如何工作的,它有转子将一个字符连接到一个完全不同的字符,例如A可能连接到F或U连接到C,这样做了三次。目前我正在使用此函数获取转子的char:
char getRotorOne(char i) {
if(i == 'a') {
return 'g';
}if(i == 'b') {
return 'A';
}if(i == 'c') {
return 'o';
}
这个问题的主要问题是它需要很长时间才能编写,效率似乎很低,我认为必须有更好的方法。另一个问题是在原来的谜机器上只有26个字母的字母在这上面有ascii(32-126)的94个可录制的字符有没有其他更简单的方法可以做到这一点?如果您认为这个问题不清楚或者您不明白请告诉我而不是仅仅标记我的帖子,那么您可以帮助我改进我的问题。
答案 0 :(得分:7)
使用表格!方便的是,C字符串文字是字符数组。所以你可以这样做:
// abc
const char* lower_mapping = "gAo";
// ABC
const char* upper_mapping = "xyz";
char getRotorOne(char i) {
if (i >= 'a' && i <= 'z') return lower_mapping[i - 'a'];
if (i >= 'A' && i <= 'Z') return upper_mapping[i - 'A'];
assert(false && "Unknown character cannot be mapped!");
}
由于char
s实际上只是小整数,并且ASCII保证a-z
和A-Z
(和0-9
)的连续范围,您可以从给定字符中减去第一个在其范围内的一个(所以,'a'
或'A'
)获得该范围的索引。然后可以使用该索引通过表查找相应的字符,在本例中只是一个简单的硬编码字符串文字。
答案 1 :(得分:2)
这是对Cameron的回答的改进。您应该为每个转子使用一个简单的char数组,但正如您所说,您希望处理32-126范围内的ASCII字符,您应该将每个映射构建为95个字符的数组:
char rotor1[95] ="aXc;-0..."; // the 95 non control ascii characters in arbitrary order
然后你用这样的方式写出你的转子功能:
char getRotorOne(char i) {
if ((i < 32) || (i > 126)) return i; // do not change non processed characters
return rotor1[i - 32]; // i - 32 is in range 0 - 94: rotor1[i - 32] is defined
}