循环移位密码
Circular shift cipher
我写了一个循环移位密码,密钥为 -10 亿到 +10 亿,用于加密最多 200 个字符的消息,包括 0 到 9、a 到 z 和 A 到 Z。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char input[215], key[11], msg[201], output[201], ch;
int i, j, k, shiftkeychar, shiftkeynum;
printf("Input: ");
gets(input);
for (i = 0; input[i] != ':'; i++)
key[i] = input[i];
key[i] = '[=10=]';
i++;
k = 0;
for (j = i; input[j] != '[=10=]'; j++) {
msg[k] = input[j];
k++;
}
msg[k] = '[=10=]';
printf("\nmessage: %s\n", msg);
printf("key: %s\n", key);
shiftkeychar = atoi(key) % 26;
shiftkeynum = atoi(key) % 10;
printf("shiftkey for characters: %d\n", shiftkeychar);
printf("shiftkey for numbers: %d\n", shiftkeynum);
strcpy(output, msg);
for (i = 0; output[i] != '[=10=]'; i++) {
ch = output[i];
if (ch >= 'A' && ch <= 'Z') {
ch = ch + shiftkeychar;
if (ch > 'Z') {
ch = ch - 'Z' + 'A' - 1;
}
else if (ch < 'A') {
ch = ch + 'Z' - 'A' + 1;
}
}
else if (ch >= 'a' && ch <= 'z') {
ch = ch + shiftkeychar;
if (ch > 'z') {
ch = ch - 'z' + 'a' - 1;
}
else if (ch < 'a') {
ch = ch + 'z' - 'a' + 1;
}
}
else if (ch >= '0' && ch <= '9') {
ch = ch + shiftkeynum;
if (ch > '9') {
ch = ch - '9' + '0' - 1;
}
else if (ch < '0') {
ch = ch + '9' - '0' + 1;
}
}
output[i] = ch;
//printf("output[%d]: %c", i, ch);
}
printf("Output: %s", output);
return 0;
}
这种循环移位密码适用于大写字母和数字。但是对于小写字母,例如如果消息是 'xyz' 并且密钥大于 5(即 6,7,...25),它会生成一些任意输出。输入格式为:"key:message"。输出是:"encrypted message".
您的字符 ch
是一个字符,在 C 中可能有符号也可能没有符号。在你的机器上,它似乎是有符号的,这意味着你可以存储从 −128 到 127 的值。小写字母占据了从 97 到 122 的 ASCII 码。当你说:
ch = ch + shiftkeychar;
您可能会溢出字母表后面字母的签名 char
。从技术上讲,这是 未定义的行为;在实践中你可能会得到负值,这将导致以后出现奇怪的字符。
要解决您的问题,请将 ch
设为 int
。
我写了一个循环移位密码,密钥为 -10 亿到 +10 亿,用于加密最多 200 个字符的消息,包括 0 到 9、a 到 z 和 A 到 Z。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char input[215], key[11], msg[201], output[201], ch;
int i, j, k, shiftkeychar, shiftkeynum;
printf("Input: ");
gets(input);
for (i = 0; input[i] != ':'; i++)
key[i] = input[i];
key[i] = '[=10=]';
i++;
k = 0;
for (j = i; input[j] != '[=10=]'; j++) {
msg[k] = input[j];
k++;
}
msg[k] = '[=10=]';
printf("\nmessage: %s\n", msg);
printf("key: %s\n", key);
shiftkeychar = atoi(key) % 26;
shiftkeynum = atoi(key) % 10;
printf("shiftkey for characters: %d\n", shiftkeychar);
printf("shiftkey for numbers: %d\n", shiftkeynum);
strcpy(output, msg);
for (i = 0; output[i] != '[=10=]'; i++) {
ch = output[i];
if (ch >= 'A' && ch <= 'Z') {
ch = ch + shiftkeychar;
if (ch > 'Z') {
ch = ch - 'Z' + 'A' - 1;
}
else if (ch < 'A') {
ch = ch + 'Z' - 'A' + 1;
}
}
else if (ch >= 'a' && ch <= 'z') {
ch = ch + shiftkeychar;
if (ch > 'z') {
ch = ch - 'z' + 'a' - 1;
}
else if (ch < 'a') {
ch = ch + 'z' - 'a' + 1;
}
}
else if (ch >= '0' && ch <= '9') {
ch = ch + shiftkeynum;
if (ch > '9') {
ch = ch - '9' + '0' - 1;
}
else if (ch < '0') {
ch = ch + '9' - '0' + 1;
}
}
output[i] = ch;
//printf("output[%d]: %c", i, ch);
}
printf("Output: %s", output);
return 0;
}
这种循环移位密码适用于大写字母和数字。但是对于小写字母,例如如果消息是 'xyz' 并且密钥大于 5(即 6,7,...25),它会生成一些任意输出。输入格式为:"key:message"。输出是:"encrypted message".
您的字符 ch
是一个字符,在 C 中可能有符号也可能没有符号。在你的机器上,它似乎是有符号的,这意味着你可以存储从 −128 到 127 的值。小写字母占据了从 97 到 122 的 ASCII 码。当你说:
ch = ch + shiftkeychar;
您可能会溢出字母表后面字母的签名 char
。从技术上讲,这是 未定义的行为;在实践中你可能会得到负值,这将导致以后出现奇怪的字符。
要解决您的问题,请将 ch
设为 int
。