我有一个程序以 ROT13 编码对给定的字符串进行编码。但是,我意识到,如果我不在
break;
的某处添加 if statement
,编码就会部分错误
我想明白为什么。请参阅下面的代码。
#include <stdio.h>
int main() {
char s1[] = "ROT13 (\"rotate by 13 places\", sometimes hyphenated ROT-13) is a simple letter substitution cipher.\n";
char s2[] = "ROT13 (\"rotate by 13 places\", sometimes hyphenated ROT-13) is a simple letter substitution cipher.\n";
char codec[] = "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ";
char ROT13[] = "nNoOpPqQrRsStTuUvVwWxXyYzZaAbBcCdDeEfFgGhHiIjJkKlLmM";
int i =0;
int j =0;
printf("%s\n",s1); //prints source string
for (i = 0; s1[i] !='\0'; i++) {
for (j = 0; codec[j] != '\0'; j++) {
if (s1[i] == codec[j]) {
s1[i] = ROT13[j];
break;
}
}
}
printf("%s\n", s1); //Output after ROT13 encoding
for (i = 0; s2[i] !='\0'; i++) {
for (j = 0; codec[j] != '\0'; j++) {
if (s2[i] == codec[j]) {
s2[i] = ROT13[j];
//break;
}
}
}
printf("%s", s2); //Output after ROT13 encoding
return 0;
}
break;
让它脱离循环。
例如明文为
c
,则加密为p
,如果没有break;
,则继续扫描,找到p
,再次加密为c
。
break;
是为了防止这种双重加密。
您需要在第二个字符匹配循环中使用
break
,原因与您在第一个字符匹配循环中使用 break
的原因相同。如果您在 codec
中找到与输入字符串中的当前字符匹配的字符,则替换在输入字符串中找到的字符,即 s1
或 s2
。然后,您需要在替换字符后立即退出字符匹配循环,以前进到输入字符串中的下一个字符。
如果在替换输入字符串中的当前字符后没有前进到输入字符串中的下一个字符,那么您可以匹配替换字符并进行第二次旋转。是否进行二次旋转取决于匹配的字符。
示例:如果输入字符串中的字符是
'A'
,然后将其替换为'N'
,您继续寻找匹配项,您将找到'N'
,然后您将替换原来的字符'A'
,它已经被'N'
取代,第二次被'A'
取代。这种双重替换会将输入字符旋转 13,然后再旋转 13,进行两次旋转。
你会幸运地看到第 13 个字符之后的字符,无论是
'M'
还是 'm'
,因为这些字符轮流到字母表第一部分的字符,因此这些字符不会进行双重替换。
您也可以考虑使用
strchr()
标准 C 库函数来替换执行字符匹配操作的最内层循环的替代实现。
#include <stdio.h>
#include <string.h>
int main() {
// the codec contains characters arranged so that the replacement character
// for a character in the codec is the position of the matching character
// plus 13. We do this by having the characters in ascending order from
// letter A to letter Z then duplicating the first 13 characters of the
// alphabet after the letter Z. This allows us to find a match and then
// just add 13 to the index to find the replacement character.
// WARNING: This array of alphabetic characters is designed to be used
// with the strchr() function which find only the first matching
// character so duplicating the first 13 characters doesn't matter.
char codec2[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyzabcdefghijklmn";
char s1[] = "ROT13 (\"rotate by 13 places\", sometimes hyphenated ROT-13) is a simple letter substitution cipher.\n";
char s2[] = "ROT13 (\"rotate by 13 places\", sometimes hyphenated ROT-13) is a simple letter substitution cipher.\n";
printf("%s\n", s1); //prints source string
for (int i = 0; s1[i] != '\0'; i++) {
char* p;
if (p = strchr(codec2, s1[i])) {
// found a matching character so replace it.
// codec2[] contains the replacement character 13 positions after
// the matching character.
s1[i] = *(p + 13);
}
}
printf("%s\n", s1); //Output after ROT13 encoding
for (int i = 0; s2[i] != '\0'; i++) {
char* p;
if (p = strchr(codec2, s2[i])) {
s2[i] = *(p + 13);
}
}
printf("%s", s2); //Output after ROT13 encoding
return 0;
}