**移位加密** 將明文字符按固定/可變位移量在字符集中循環平移。最經典為 **凱撒密碼** (固定位移) 與 **維吉尼亞密碼** (關鍵字決定逐字符位移)。
#include <stdio.h>
#include <string.h>
#include <ctype.h>
void caesar_encrypt(char *str, int shift) {
shift %= 26;
if (shift < 0) shift += 26;
for (int i = 0; str[i]; i++) {
if (isupper(str[i]))
str[i] = 'A' + (str[i] - 'A' + shift) % 26;
else if (islower(str[i]))
str[i] = 'a' + (str[i] - 'a' + shift) % 26;
}
}
void caesar_decrypt(char *str, int shift) {
caesar_encrypt(str, 26 - shift); // 反向位移即解密
}
int main() {
char msg[] = "Hello, World!";
int key = 3;
printf("原文: %s\n", msg);
caesar_encrypt(msg, key);
printf("密文: %s\n", msg);
caesar_decrypt(msg, key);
printf("解密: %s\n", msg);
return 0;
}
void vigenere_encrypt(char *str, const char *key) {
int keylen = strlen(key);
int k = 0;
for (int i = 0; str[i]; i++) {
if (!isalpha(str[i])) continue; // 非字母保留,不消耗關鍵字位
int shift = toupper(key[k % keylen]) - 'A';
if (isupper(str[i]))
str[i] = 'A' + (str[i] - 'A' + shift) % 26;
else
str[i] = 'a' + (str[i] - 'a' + shift) % 26;
k++;
}
}
void vigenere_decrypt(char *str, const char *key) {
int keylen = strlen(key);
int k = 0;
for (int i = 0; str[i]; i++) {
if (!isalpha(str[i])) continue;
int shift = toupper(key[k % keylen]) - 'A';
if (isupper(str[i]))
str[i] = 'A' + (str[i] - 'A' - shift + 26) % 26;
else
str[i] = 'a' + (str[i] - 'a' - shift + 26) % 26;
k++;
}
}
// 介面設計
typedef enum { CAESAR, VIGENERE } CipherType;
int cipher_process(char *data, size_t len,
CipherType type, int enc_dec, // 1=encrypt, 0=decrypt
const void *key, size_t keylen); // key 為 int* 或 char*