# 原理淺說
凱薩密碼的原理就是讓英文字母依照字母表的順序往前移或是往後移\
\

*節錄自*:https://inventwithpython.com/cipherwheel/
\
\
範例:\
Key(密鑰)數字為5,將轉盤向前或向後轉動5個即可得到密碼,以外圈向後轉5為例:\
A -> F\
B -> G\
C -> H\
...\
而 V 以後之字母超出字母表範圍,因此又從 A 開始\
\
將訊息中的每個字母都以此替換就可以以此得到一個加密後的字串,例如Key(密鑰)為3時:\
明文:THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG\
密文:WKH TXLFN EURZQ IRA MXPSV RYHU WKH ODCB GRJ\
\
更多的詳細解說: [維基百科_凱薩密碼](https://zh.wikipedia.org/zh-tw/%E5%87%B1%E6%92%92%E5%AF%86%E7%A2%BC)
---
# 加密實作
## 方法簡介
由上述介紹可以得到一個簡易的凱薩加密的方法,規則如下:
1. 字母依照Key(密鑰)向前移動或向後移動
2. 字母移動若到達字母表邊界 Z 即從 A 開始
而實現上述轉盤模式規則的方法,則是可以利用字母的ASCII碼進行處裡
:::info
大寫字母ASCII碼:
| ASCII碼(十進位) | 字元 |
|:---------------:|:----:|
| 65 | A |
| 66 | B |
| 67 | C |
| ... | ... |
| 90 | Z |
而小寫字母則是:
| ASCII碼(十進位) | 字元 |
|:---------------:|:----:|
| 97 | a |
| 98 | b |
| 99 | c |
| ... | ... |
| 122 | z |
更多字元以及更詳細的解說: [維基百科_ASCII](https://zh.wikipedia.org/zh-tw/ASCII)
:::
例如:\
Key(密鑰)數字為5:字母 A 位移5個即是ASCII碼 65 + 5 即是字母 F (70)\
Key(密鑰)數字為10:字母 c 位移10個即是ASCII碼 99 + 10 即是字母 m (109)\
...以此類推(大小寫有別)\
\
而透過對於ASCII碼的數字加減即可達到位移的作用,但這只僅處理部分規則,字母位移到邊界會出現亂碼,因此需要針對邊界的狀況作處裡\
\
處裡的方法多種,比較直覺的寫法可以使用一般的判斷式,這裡提供一個比較快速的計算方法,如下圖所示:

1. 移動(紫色):先將第一個字母編號(ASCII碼)變為 0 ( A->0 , a->0 ) 再加上Key(密鑰)
2. 處理邊界(黃色):將更改後編號模除(mod, %) 26
3. 將移動後的編號位移回原本的位置(綠色)
這邊移動的意義是為了要讓編號能進行模除(mod, %),即取26(英文字母個數)餘數,這樣便不會超出字母表範圍,位移回原本的位置則是讓密文得以字元方式產生(即還原成ASCII)
## 程式撰寫
首先,將字串以多次讀入字母的方式執行(防止明文長度過長問題),便可以進行處裡
```c=
int key=5; //假設key已被使用者輸入為5
char message;
while(scanf("%c",&message)!=EOF){
printf("%c",message+key); //將ASCII碼加上key
}
```
但這僅處裡位移字串,在遇到 Z 字母邊界時會出現非字母字元,因此需要做處裡\
利用上述講解的方式,針對編號(ASCII)做處裡
```c=
if ( message>64 && message<91 ){ //針對大寫字母處裡
printf("%c",((message+key-65)%26)+65); //讓A編號為0後加上key,處裡邊界問題,在還原成字元(ASCII)
}
if ( message>96 && message<123 ){ //針對小寫字母處裡
printf("%c",((message+key-97)%26)+97); //讓a編號為0後加上key,處裡邊界問題,在還原成字元(ASCII)
}
```
:::warning
:warning:
凱薩密碼僅對大小寫字母做運算,因此在遇到數字或是特殊字元需要作為例外處理!
:::
以上就是程式主要的演算介紹,其餘輸入方式、介面格式就不另行贅述,僅範例程式作為參考\
更多原始碼參考:[Github](https://github.com/aaronhuang1005/cracking-code)
\
\
`encrypted.c`
```c=
/*
------------------------------------
Created on Tue Jul 11 23:11:19 2023
@author: Aaron huang
------------------------------------
*/
#include<stdio.h>
int main(){
int key=0;
printf("\nInput the key:");
while(scanf("%d",&key)!=EOF){ //input a key number from user
printf("Input the message(type 0 to exit):\n");
char message='0'; //set the defualt character to '0'
while(scanf("%c",&message)!=EOF){
//printf("Ascii code:%d\n",message);
if(message==48){ //if user input a '0'(ascii code is 48), exit this loop
break;
}else if( message>64 && message<91 ){ //if user input upper character
printf("%c",((message+key-65)%26)+65);
}else if( message>96 && message<123 ){ //if user input lower character
printf("%c",((message+key-97)%26)+97);
}else if(message==32){ //if user input space
printf(" ");
}else{ //other word was not define
if( message!=10){ //except '\n'
printf("\nUndefine word:[ %c ]...\n",message);
}
}
}
printf("\n\tInput the key:");
}
return 0;
}
```
\
`執行結果:`
