需求:輸入字符串,按密鑰序列 4,9,6,2,8,7,3 循環加密(ASCII 碼加密鑰),解密後與原文比對,一致則輸出解密文,否則報錯。
encrypt[i] = source[i] + key[source[i] % 7]。此處取模 7 使密鑰索引與字符值關聯,增加一定隨機性。decrypt[i] = encrypt[i] - key[source[i] % 7]。注意:解密時仍用原文 source[i] 計算索引,而非密文,否則無法還原。strcmp(source, decrypt) == 0 判斷解密是否成功。#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEN 80
int main(void) {
char source[MAX_LEN], encrypt[MAX_LEN], decrypt[MAX_LEN];
int key[7] = {4, 9, 6, 2, 8, 7, 3};
size_t i, len;
printf("請輸入字符串: ");
if (fgets(source, MAX_LEN, stdin) == NULL) return 1;
// 去除 fgets 讀入的換行符
len = strlen(source);
if (len > 0 && source[len - 1] == '\n')
source[--len] = '\0';
// 加密
for (i = 0; i < len; i++)
encrypt[i] = source[i] + key[source[i] % 7];
encrypt[len] = '\0';
// 解密
for (i = 0; i < len; i++)
decrypt[i] = encrypt[i] - key[source[i] % 7];
decrypt[len] = '\0';
printf("加密結果: %s\n", encrypt);
// 驗證
if (strcmp(source, decrypt) == 0)
printf("解密成功: %s\n", decrypt);
else
printf("解密失敗!\n");
return 0;
}
| 項目 | 原代碼問題 | 改進方案 |
|---|---|---|
| 輸入函數 | 使用 gets,極度不安全,已被 C11 移除 | 改用 fgets,限制長度,防止緩衝區溢出 |
| 密鑰索引 | source[i] % 7 導致索引僅取決於字符值,相同字符加密固定 | 可改為 i % 7 使位置相關,或引入更複雜的流密鑰生成器 |
| 字符溢出 | 加密後 ASCII 碼可能超出 0-127 範圍,導致顯示亂碼或截斷 | 建議對 256 取模:(source[i] + key[...]) % 256,解密時同理 |
| 可打印性 | 加密結果可能包含控制字符,無法正常顯示/傳輸 | 實際應用常用 Base64、Hex 編碼將密文轉為可打印字符 |
rb/wb 逐塊處理大文件。本例屬教學演示級算法,切勿用於真實數據保護。理解其原理有助於進階學習密碼學基礎。