<<c与指针>>第9章中的一道题
有一种技巧可以对数据进行加密,并使用一个单词作为它的密匙.下面是它的工作原理:首先,选择一个单词作为密匙,如TRAILBLAZERS.如果单词中包含有重复的字母,只保留第一个,其余几个丢弃.现在,修改过的那个单词列于字母表的下面,
如下所示:
A B C D E F G H I Z K L M N O P Q R S T U V W X Y Z
T R A I L B Z E S
最后,底下那行用字母表中剩余的字母填充完整:
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
T R A I L B Z E S C D F G H J K M N O P Q U V W X Y
在对信息加密时,信息中的每个字母被固定于顶上那行,并用下面那行的对应之母--取代原文字母.因此,使用这个密匙,ATTACK AT DAWN(黎明时攻击)就会被加密成TPPTAD TP ITVH.
这个题材共有三个程序.
第一个程序:
编写函数
int prepare_key(char *key);
它接受一个字符串参数,它的内容就是需要使用的密匙单词.函数根据上面描述的方法把它转换成一个包含编好码的字符数组.假定key参数是一个字符数组,其长度至少可以容纳27个字符.函数必须把密匙中的所有字符要么转换成大写字母,要么转换成小写字母(随你选择),并从单词中去除重复的字母,然后再用字母表中剩余的字母按照你原先所选择的大小写形式填充到key数组中.如果处理成功,函数返回真,如果key参数为空或包含任何非字母字符,函数返回假.
第二个程序:
编写函数
void encrypt(char *data,char const *key);
它使用前题prepare_key函数所产生的密匙对data中的字符进行机密.data中的非字母字符不作修改,但字母字符则用密匙所提供的编码过的字符--取代原字符.字母字符的大小写状态应该保留.
第三个程序:
编写函数
void decrypt (char *data,char const *key);
它接受一个加过密的字符串参数,它的任务是重现原来的信息.除了它是用于解密之外.它的工作原理应该与encryp相同.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define BOOL int
#define FALSE 0
#define TRUE 1
#define SIZE 27
char const key_chars[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
BOOL prepare_key (char *key);
void encrypt(char *data,char const *key);
void decrypt(char *data, char const *key);
void showdata(char *data);
int main(void)
{
char data[SIZE],key[SIZE];
BOOL flag=FALSE;
printf("键入加密密匙: ");
while(gets(key)!=NULL && key[0]!='\n')
{
flag=prepare_key(key);
if(!flag)
{
printf("密匙参数有误,请输入英文单词: ");
continue;
}
else
break;
}
if(flag)
{
printf("键入加密数据: ");
gets(data);
encrypt(data,key);
printf("显示加密后的数据:\n");
showdata(data);
decrypt(data,key);
printf("显示解密后的数据:\n");
showdata(data);
}
getchar();
return 0;
}
BOOL prepare_key (char *key)
{
BOOL flag[SIZE]={FALSE};
int i,j,k,n;
if(key==NULL)
return FALSE;
else
for(i=0,n=strlen(key);i<n;i++)
if(!isalpha(key[i]))
return FALSE;
for(i=0,n=strlen(key);i<n;i++)
{
if(key[i]!='\0')
key[i]=toupper(key[i]);
for(j=i+1;j<n;j++)
{
if(key[i]==key[j])
{
for(k=j;k<n;k++)
key[k]=key[k+1];
}
}
}
for(i=0,n=strlen(key);i<n;i++)
{
for(j=0;j<SIZE;j++)
if(key[i]==key_chars[j])
flag[j]=TRUE;
}
for(i=0;i<SIZE;i++)
{
if(flag[i]==FALSE)
{
key[n]=key_chars[n];
n++;
}
}
return TRUE;
}
void encrypt(char *data,char const *key)
{
int i;
for(i=0;i<SIZE;i++)
{
if(islower(data[i]))
data[i]=tolower(key[i]);
if(isupper(data[i]))
data[i]=toupper(key[i]);
}
}
void decrypt(char *data, char const *key)
{
int i;
for (i=0;i<SIZE;i++)
{
if(islower(data[i]))
data[i]=tolower(key_chars[i]);
if(isupper(data[i]))
data[i]=toupper(key_chars[i]);
}
}
void showdata( char *data)
{
puts(data);
}
[解决办法]
我贴出我的代码,
#include <iostream>#include <string>using namespace std;bool FindChar(string &str,int start_index,int end_index,char ch){ for (int i=start_index;i<=end_index;i++) { if (str[i]==ch) { return true; } } return false;}bool IsChar(char ch){ if ((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) { return true; } else { return false; }}void PrepareKey(string &key_word,string &code_str){ int i,j=0; for (i=0;i<key_word.length();i++) { if (!FindChar(code_str,0,code_str.length()-1,key_word[i])) { code_str=code_str+key_word[i]; } } for (i=0;i<26;i++) { if (!FindChar(code_str,0,code_str.length()-1,'A'+i)) { code_str=code_str+char('A'+i); } }}void Encrypt(const string &code_str,string &data,string &code){ int i; char temp; for (i=0;i<data.length();i++) { temp=data[i]; if (IsChar(temp)) { temp=temp&0x7f; code=code+code_str[temp-'A']; } else { code=code+data[i]; } }}int FindePosition(const string &code_str,char ch){ for (int i=0;i<code_str.length();i++) { if (code_str[i]==ch) { return i; } } return -1;}void Decrypt(const string &code_str,string &code,string &data){ int i; char temp; for (i=0;i<code.length();i++) { temp=code[i]; if (IsChar(temp)) { temp=temp&0x7f; int pos=FindePosition(code_str,temp); data=data+char('A'+pos); } else { data=data+code; } }}int main(){ string sour_str="ABCDEFGHIJKLMNOPQRSTUVWXYZ"; string key_word;//用于生成密钥的单词 cin>>key_word; string code_str;//产生的密钥序列 PrepareKey(key_word,code_str);//产生密钥序列的函数 string data="ATTACK AT DAWN";//明文 string code;//密文为空 Encrypt(code_str,data,code);//用于加密的操作,密码存储在code中 string new_data;//明文为空 Decrypt(code_str,code,new_data);//将密文code解密得到的明文的函数 return 0;}