古典密码学可以分为代替密码(也叫做移位密码)和置换密码(也叫做换位密码)两种,其中代替密码典型的有Caesar密码,仿射变换等,置换密码有单表置换和多表置换等。
下面是几种常见古典密码算法的实现。
1.Caesar密码
void encrypt(char* text,int k,char cipher[1024]){ int a[26];int A[26]; int m; for(int i=97;i<123;i++){ a[i-97]=i; A[i-97]=i-32; } int len=strlen(text); for(int j=0;j<len;j++){ int t=text[j]; if(96<t&&t<123){ m=(text[j]+k-97)%26; cipher[j]=a[m]; } else if(64<t&&t<91){ m=(text[j]+k-65)%26; cipher[j]=A[m]; } else cipher[j]=' '; } } void decrypt(char* cipher,int k,char text[1024]){ int a[26];int A[26]; int m; for(int i=97;i<123;i++){ a[i-97]=i; A[i-97]=i-32; } int len=strlen(cipher); for(int i=0;i<len;i++){ int t=cipher[i]; if(96<t&&t<123){ m=(cipher[i]-k-71)%26; text[i]=a[m]; } else if(64<t&&t<91){ m=(cipher[i]-k-39)%26; text[i]=A[m]; } else text[i]=' '; } }
2.单表置换
//#include "Ceasar.h" #include "stdafx.h" void transkey(char* key,char table[27]){ char tem[100]={0}; char table1[30]={0}; for(int i=97;i<123;i++) table1[i-97]=i; int len1=strlen(key); strcpy(tem,key); strcpy(tem+len1,table1); int len=strlen(tem); int k=1;int flag; if(isupper(tem[0])) tem[0]+=32; table[0]=tem[0]; for(int i=1;i<strlen(tem)&&k<26;i++){ if(!isalpha(tem[i])) continue; if(isupper(tem[i])) tem[i]+=32; flag=0; for(int j=0;j<k;j++){ if(table[j]==tem[i]){ flag=1;break; } } if(!flag) table[k++]=tem[i]; } } void encrypt(char* text,char* key,char cipher[1024]){ char table[27]={0}; transkey(key,table); int len=strlen(text); for(int i=0;i<len;i++){ if(!isalpha(text[i])) cipher[i]=text[i]; else if(islower(text[i])) cipher[i]=table[text[i]-97]; else cipher[i]=table[text[i]-65]-32; } } void ttable(char table[27]){ char ip[30]={0}; for(int i=97;i<122;i++){ ip[table[i-97]-'a']=i; } memcpy(table,ip,26); } void decrypt(char* cipher,char* key,char text[1024]){ char table[27]={0}; transkey(key,table); ttable(table); int len=strlen(cipher); for(int i=0;i<len;i++){ if(!isalpha(cipher[i])) text[i]=cipher[i]; else if(islower(cipher[i])) text[i]=table[cipher[i]-97]; else text[i]=table[cipher[i]-65]-32; } }
3.仿射变换
//#include "Ceasar.h" #include "stdafx.h" void encrypt(char* text,int k1,int k2,char cipher[1024]){ int len=strlen(text); int e=0; for(int j=0;j<len;j++){ if(!isalpha(text[j])){ cipher[j]=text[j]; } else if(islower(text[j])){ e=text[j]-'a'; cipher[j] = (e*k1+k2) % 26 + 'a'; } else{ e=text[j]-'A'; cipher[j] = (e*k1+k2) % 26 + 'A'; } } } int rec(int k,int m){ int i=1; int j=0; while(1){ for(j=0;k*j<m*i+1;j++){} if(k*j==m*i+1) break; else i++; } return j; } void decrypt(char* cipher,int k1,int k2,char text[1024]){ int len=strlen(cipher); int e=0; int k3=rec(k1,26); for(int i=0;i<len;i++){ if(!isalpha(cipher[i])){ text[i]=cipher[i]; } else if(islower(cipher[i])){ e=cipher[i]-'a'; text[i] = (k3*(e-k2+26))% 26 + 'a'; } else{ e = cipher[i] - 'A'; text[i]=((e-k2+26)*k3)% 26 +'A'; } } }
4.维吉尼亚密码
//#include "Ceasar.h" #include "stdafx.h" void encrypt(char* text,char* key,char cipher[1024]){ int len=strlen(text); int lenkey=strlen(key); for(int j=0;j<lenkey;j++) //keyСд if(isupper(key[j])) key[j]+=32; for(int i=0;i<len;i++){ if(!isalpha(text[i])) cipher[i]=text[i]; else if(isupper(text[i])) cipher[i]=(text[i]-'A'+key[i%lenkey]-'a')%26+'A'; else cipher[i]=(text[i]-'a'+key[i%lenkey]-'a')%26+'a'; } } void decrypt(char* cipher,char* key,char text[1024]){ int len=strlen(cipher); int lenkey=strlen(key); for(int j=0;j<lenkey;j++) //keyСд if(isupper(key[j])) key[j]+=32; for(int i=0;i<len;i++){ if(!isalpha(cipher[i])) text[i]=cipher[i]; else if(isupper(cipher[i])) text[i]=(26+cipher[i]-'A'-(key[i%lenkey]-'a'))%26+'A'; else text[i]=(26+cipher[i]-'a'-(key[i%lenkey]-'a'))%26+'a'; } }