首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> C 語言問答

C語言資料加密實戰:五位整數加密演算法完整解析

     編輯:C 語言問答

題目需求

輸入一個五位整數,按以下規則加密:

  1. 每位數字加 6
  2. 用和除以 8 的餘數取代該數字(即 (digit + 6) % 8)
  3. 交換第 1 位與第 5 位,第 2 位與第 4 位

演算法步驟拆解

原始數字:d1 d2 d3 d4 d5  (d1 為萬位,d5 為個位)

步驟 1:拆解數字到陣列 a[0..4]
a[0] = d5 (個位)
a[1] = d4 (十位)
a[2] = d3 (百位)
a[3] = d2 (千位)
a[4] = d1 (萬位)
→ 陣列索引 0 對應個位,方便後續處理

步驟 2:加密變換
for i = 0..4:
    a[i] = (a[i] + 6) % 8

步驟 3:位置交換
swap(a[0], a[4])  // 個位 ↔ 萬位
swap(a[1], a[3])  // 十位 ↔ 千位
// a[2] (百位) 不動

步驟 4:重組結果
result = a[4]*10000 + a[3]*1000 + a[2]*100 + a[1]*10 + a[0]

完整標準 C 實作

#include <stdio.h>
#include <stdlib.h>

#define N 5

// 將五位整數拆解到陣列,索引 0 為個位
void decompose(int num, int digits[N]) {
    for (int i = 0; i < N; ++i) {
        digits[i] = num % 10;
        num /= 10;
    }
}

// 加密變換:(digit + 6) % 8
void encrypt_transform(int digits[N]) {
    for (int i = 0; i < N; ++i) {
        digits[i] = (digits[i] + 6) % 8;
    }
}

// 位置交換:1↔5, 2↔4 (陣列索引 0↔4, 1↔3)
void swap_positions(int digits[N]) {
    int t = digits[0]; digits[0] = digits[4]; digits[4] = t;
    t = digits[1]; digits[1] = digits[3]; digits[3] = t;
}

// 陣列重組為整數
int compose(const int digits[N]) {
    int result = 0;
    for (int i = N - 1; i >= 0; --i) {
        result = result * 10 + digits[i];
    }
    return result;
}

int encrypt_number(int num) {
    int digits[N];
    decompose(num, digits);
    encrypt_transform(digits);
    swap_positions(digits);
    return compose(digits);
}

int main() {
    int input;
    printf("請輸入一個五位整數:");
    if (scanf("%d", &input) != 1) return 1;
    
    // 驗證輸入為五位正整數 (10000-99999)
    if (input < 10000 || input > 99999) {
        printf("Error Data: 輸入必須為五位正整數\n");
        return 1;
    }

    int encrypted = encrypt_number(input);
    printf("加密結果:%05d\n", encrypted);  // %05d 補齊前導零
    return 0;
}

測試驗證

輸入拆解+6%8交換後輸出
12345[5,4,3,2,1][3,2,1,0,7][7,0,1,2,3]70123
99999[9,9,9,9,9][7,7,7,7,7][7,7,7,7,7]77777
10000[0,0,0,0,1][6,6,6,6,7][7,6,6,6,6]76666
56789[9,8,7,6,5][7,6,5,4,3][3,4,5,6,7]34567

原始代碼問題分析

題目提供的代碼存在多個問題:

  • #include"stdio.h" → 應為 <stdio.h>
  • 全域陣列 int a[N] 耦合度高,函數間隱性依賴
  • copy 函數邏輯混亂:a[N-i-1] = d%10 實際上是逆序存放,但迴圈條件與索引運算易出錯
  • void main() 非標準,應為 int main()
  • getch() 非標準 (conio.h),可移植性差
  • 輸入驗證 if(d<=9999) 不完整,未檢查上界 99999

最佳實踐總結

  1. 單一職責:拆解、變換、交換、重組各自獨立函數,易測試、易維護。
  2. 避免全域變數:透過參數傳遞陣列,降低耦合。
  3. 輸入驗證完整:檢查位數範圍、非數字輸入。
  4. 輸出格式化:%05d 保證五位輸出含前導零。
  5. 標準 C:無 conio.h、getch(),純 stdio.h,跨平台編譯。

延伸思考

  • 此加密為可逆嗎?是,因 (x+6)%8 在模 8 下可逆(逆運算:(y+2)%8),交換操作也是自逆的。
  • 若輸入非五位數?擴充為字串處理任意長度。
  • 安全性極低,僅供教學演示置換與替換密碼基本概念。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved