古典密码学可以分为代替密码(也叫做移位密码)和置换密码(也叫做换位密码)两种,其中代替密码典型的有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';
}
}