實驗一、傳統密碼演算法
一、實驗目的及任務
通過編程實現替代密碼演算法和置換密碼演算法,加深對古典密碼體制的瞭解,為深入學習密碼學奠定基礎
二、實驗環境
運行Windows作業系統的PC機,具有C語言編譯環境。
三、實驗原理
古典密碼演算法曆史上曾被廣泛應用,大都比較簡單,使用手工和機械操作來實現加密和解密.它的主要應用對象是文字資訊,利用密碼演算法實現文字資訊的加密和解密.下面介紹兩種常見的具有代表性的古典密碼演算法,以協助讀者對密碼演算法建立一個初步的印象.
1. 替代密碼
替代密碼演算法的原理是使用替代法進行加密,就是將明文中的字元用其它字元替代後形成密文.例如:明文字母a,b,c,d ,用D,E,F,G做對應替換後形成密文.
替代密碼包括多種類型,如單表替代密碼,多明碼替代密碼,多字母替代密碼,多表替代密碼——.
1)下面我們先介紹一種典型的單表替代密碼,愷撒(caesar)密碼,又叫迴圈移位密碼.它的加密方法,就是將明文中的每個字母用此字元在字母表中後面第k個字母替代.它的加密過程可以表示為下面的函數:
E(m)=(m+k) mod n
其中:m為明文字母在字母表中的位置數;n為字母表中的字母個數;k為密鑰;E(m)為密文字母在字母表中對應的位置數.
例如,對於明文字母H,其在字母表中的位置數為7,設k=4,則按照上式計算出來的密文為L:
E(7) = (m+k) mod n = (7+4) mod 26 = 11 = L
2)下面是一種典型的多表替代密碼:維吉尼亞密碼,它選擇一個片語作為密鑰,密鑰中每個字母用來確定一個代換表,每個密鑰字母用來加密一個明文字母。例如密鑰字母為a,明文字母為c,則密文字母為0+2(mod26)=2,也就是c。直到所有的密鑰字母用完,後再從頭開始,使用第一個密鑰字母加密。也就是說,密鑰迴圈使用。
例:明文為attack begins at five,密鑰為cipher,
attack begins at five 明文
+ cipher cipher ci pher 密鑰
----------------------------------------------
= cbihgb dmvprj cb upzv 密文
去除空格後為cbihgbdmvprjcbupzv
2. 置換密碼
置換密碼演算法的原理是不改變明文字元,只將字元在明文中的排列順序改變,從而實現明文資訊的加密.置換密碼有時又稱為換位密碼.
矩陣換位法是實現置換密碼的一種常用方法.它將明文中的字母按照給的順序安排在一個矩陣中,然後用根據密鑰提供的順序重新組合矩陣中字母,從而形成密文.例如,明文為attack begins at five,密鑰為cipher,將明文按照每行6列的形式排在矩陣中,形成如下形式:
a t t a c k
b e g i n s
a t f i v e
根據密鑰cipher中各字母在字母表中出現的先後順序,給定一個置換:
1 2 3 4 5 6
F= 1 4 5 3 2 6 1
根據上面的置換,將原有矩陣中的字母按照第1列,第4列,第5列,第3列,第2列,第6列的順序排列,則有下面形式:
a a c t t k
b i n g e s
a i v f t e
從而得到密文:abatgftetcnvaiikse
其解密的過程是根據密鑰的字母數作為列數,將密文按照列,行的順序寫出,再根據由密鑰給出的矩陣置換產生新的矩陣,從而恢複明文.
四、 實驗步驟
(1)根據實驗原理部分對替代密碼演算法的介紹,自己建立明文資訊,並選擇一個密鑰k,編寫替代密碼演算法的實現程式,實現加密和解密操作.
(2)根據實驗原理部分對置換密碼演算法的介紹,自己建立明文資訊,並選擇一個密鑰,編寫置換密碼演算法的實現程式,實現加密和解密操作.
五:實驗結果:
1:L
2:abatgftetcnvaiikse
六、實驗思考題
1:替代密碼的原理是什麼。
2:置換密碼的原理是什麼。
替代密碼代碼如下:
#include<stdio.h>#include<math.h>#include<string.h>#define N 500int main() {int i=0,k,m,n,l;char str1[N],str2[N];/*C=M+K...K is key...*/printf("輸入要加密的明文M\n");gets(str1);/*輸入要加密的明文M*/printf("輸入密鑰K\n");scanf("%d",&k);/*輸入密鑰K*/m=strlen(str1);/*測試明文的長度*/printf("明文的長度是%d\n",m);printf("\n *\n *\n *\n***\n *\n");printf("ciphertext(C) is ::\n\n");for(i=0;i<m;i++)/*加密的過程*/{n=(int)str1[i];/*將字元轉換成ASCII*/if(str1[i]==' ')/*如果字串中出現空格返回空格*/{printf(" ");str2[i]=str1[i];}else if(n>96&&n<123)/*對小寫進行加密*/{n=(n-97+k)%26;if(n<0)n=26+n;l=(char)(n+97);printf("%c",l);str2[i]=l;}else if(n>64&&n<91)/*對大寫進行加密*/{n=(n-65+k)%26;if(n<0)n=26+n;l=(char)(n+97);printf("%c",l);str2[i]=l;}}str2[i]='\0';/*--------------------------------*/printf("\n\nThe C length is %d",strlen(str2));printf("\n\n *\n *\n *\n***\n *\n");printf("When the ciphertext is '%s',\nThe password program is...::\n\n",str2);m=strlen(str2);for(i=0;i<m;i++)/*解密過程*/{n=(int)str2[i];/*將字元轉換成ASCII*/if(str2[i]==' ')/*如果是空格,返回的也是空格*/{printf(" ");}else if(n>96&&n<123)/*對小寫進行解密*/{n=(n-97-k)%26;if(n<0)n=26+n;l=(char)(n+97);printf("%c",l);}else if(n>64&&n<91)/*對大寫進行解密*/{n=(n-65-k)%26;if(n<0)n=26+n;l=(char)(n+97);printf("%c",l);}}str1[i]='\0';return 0;}
置換密碼代碼如下:
#include<stdio.h> #include<math.h>#include<string.h>#define N 100int main(){/*----------------------------*/int i,j,lenK,lenM,m,n,temp;int T[N];char K[N],M[N],C[N],Temp1[N],Temp2[N],Temp3[N];/*----------------------------*/printf("輸入明文M\n");/*輸入明文M*/gets(M);printf("輸入密鑰K\n");/*輸入密鑰K*/gets(K);lenK=strlen(K);lenM=strlen(M);/*測設長度*/m=lenM/lenK;n=lenK;/*定義矩陣的長和寬*/for(i=0;i<lenK;i++)/*對密鑰進行數字排序*/{temp=0;for(j=0;j<lenK;j++){if((int)K[i]<(int)K[j]){temp+=1;}}T[i]=lenK-temp;printf("%d ",T[i]);/*輸出各字元對應的數字順序*/}/*--------------------------------*/printf("\n\nFirst........\n\n");for(i=0;i<m;i++)/*根據密鑰將明文排列成矩陣*/{for(j=0;j<n;j++){Temp1[i*lenK+j]=M[i*lenK+j];printf("%c?",Temp1[i*lenK+j]);}printf("\n");}Temp1[lenM]='\0';/*--------------------------------*/printf("\nSecond........\n\n");/*進行第一次置換*/for(i=0;i<lenK;i++){for(j=0;j<m;j++){Temp2[j*lenK+i]=Temp1[j*lenK+T[i]-1];}}Temp2[lenM]='\0';for(i=0;i<m;i++){for(j=0;j<lenK;j++){printf("%c?",Temp2[i*lenK+j]);}printf("\n");}/*-------------------------------*/printf("\nThird.......\n\n");/*進行第二次置換*/for(i=0;i<lenK;i++){for(j=0;j<m;j++){Temp3[j*lenK+i]=Temp2[j*lenK+T[i]-1];}}Temp3[lenM]='\0';for(i=0;i<m;i++){for(j=0;j<lenK;j++){printf("%c ",Temp3[i*lenK+j]);}printf("\n");}/*-----------------------------*/printf("輸出結果\n");for(j=0;j<lenK;j++){for(i=0;i<m;i++){printf("%c",Temp3[i*lenK+j]);}}return 0; }