文件加密(环)

【问题描述】

有一种文本文件加密方法,其方法如下:

1、密钥由所有ASCII码可见字符(ASCII码编码值32-126为可见字符)组成,密钥长度不超过32个字符;

2、先将密钥中的重复字符去掉,即:只保留最先出现的字符,其后出现的相同字符都去掉;

3、将不含重复字符的密钥和其它不在密钥中的可见字符(按字符升序)连成一个由可见字符组成的环,密钥在前,密钥的头字符为环的起始位置;

4、设原密钥的第一个字符(即环的起始位置)作为环的开始位置标识,先从环中删除第一个字符(位置标识则移至下一个字符),再沿着环从下一个字符开始顺时针以第一个字符的ASCII码值移动该位置标识至某个字符,则该字符成为第一个字符的密文字符;然后从环中删除该字符,再从下一个字符开始顺时针以该字符的ASCII码值移动位置标识至某个字符,找到该字符的密文字符;依次按照同样方法找到其它字符的密文字符。当环中只剩一个字符时,则该剩下的最后一个字符的密文为原密钥的第一个字符。

下面以可见字符集只由小写字母组成为例来说明对应密文字符集生成过程。如果密钥为:helloworld,将密钥中重复字符去掉后为:helowrd,将不在密钥中的小写字母按照升序添加在密钥后,即形成字符串:helowrdabcfgijkmnpqstuvxyz,该字符串形成的环如下图所示:

huan.jpg

明码的第一个字母为h,h也是环的起始位置。h的ASCII码制为104,先把h从环中删除,再从下一个字母e开始顺时针沿着环按其ASCII值移动位置标识(即移动位置标识104次)至字母w,则h的密文字符为w。w的ASCII码制为119,然后将w从环中删除,再从下一个字母r开始顺时针沿着环移动位置标识119次至字母为l,则w的密文字符为l。依次按照同样方法找到其它字母的密文字符。环中剩下的最后一个字母为x,则x的密文字符为明码的第一个字母h。按照这种方法形成的密文转换字符表为:

biao.jpg

上方为原文字符,下方为对应的密文字符。由所有ASCII可见字符集组成的字符集密文字符生成方式与上例相同。

编写程序实现上述文件加密方法。密钥从标准输入读取,待加密文件为当前目录下的in.txt文件,该文件中的字符若是可见字符,则按照上述方法进行加密,否则原样输出(例如:回车换行符),加密后生成的密文文件为当前目录下的in_crpyt.txt。

【输入形式】

密钥是从标准输入读取的一行字符串,可以包含任意ASCII码可见字符(ASCII码编码值32-126为可见字符),长度不超过32个字符。

【输出形式】

加密后生成的密文文件为当前目录下的in_crpyt.txt。

【样例输入】

C Programming(Second Edition)

假设in.txt文件内容为:

This book is meant to help the reader learn how to program in C. It is the definitive reference guide, now in a second edition. Although the first edition was written in 1978, it continues to be a worldwide best-seller. This second edition brings the classic original up to date to include the ANSI standard.

From the Preface:

【样例输出】

in_crpyt.txt文件内容为:

KgklW#33>WklWA\^M8W83Wg\Z,W8g\WP\^u\PWZ\^PMWg3jW83W,P30P^AWkMWX5W.8WklW8g\Wu\EkMk8kt\WP\E\P\MR\W0-ku\+WM3jWkMW^Wl\R3MuW\uk8k3M5WIZ8g3-0gW8g\WEkPl8W\uk8k3MWj^lWjPk88\MWkMW'71G+Wk8WR3M8kM-\lW83W#\W^Wj3PZujku\W#\l8Jl\ZZ\P5WKgklWl\R3MuW\uk8k3MW#PkM0lW8g\WRZ^llkRW3Pk0kM^ZW-,W83Wu^8\W83WkMRZ-u\W8g\WIOY.Wl8^Mu^Pu5

4P3AW8g\WdP\E^R\(

【样例说明】

输入的密钥为C Programming(Second Edition),由该密钥生成的字符串环中字符依次为:

C Progamin(SecdEt)!"#$%&'*+,-./0123456789:;<=>?@ABDFGHIJKLMNOQRTUVWXYZ[\]^_`bfhjklpqsuvwxyz{|}~

形成的字符转换字符表(第一行为原ASCII字符,第二行为对应的密文字符)为:

image.png

按照该密文转换字符表将in.txt中的内容转换成加密字符输出到in_crpyt.txt中。

 

【题解】

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<string.h>
  4 struct encode
  5 {
  6     unsigned char in[95];
  7     unsigned char out[95];
  8 }que;
  9 struct cricle
 10 {
 11     unsigned char ch;
 12     struct cricle *next;
 13 };
 14 unsigned char a[100],b[100];
 15 int main()
 16 {
 17     struct cricle *first,*p,*q;
 18     unsigned char cha;
 19     char str;
 20     int i,j,m;
 21     FILE *in,*out;
 22 
 23     gets(a);
 24 
 25     for(i=0;i<100;i++)
 26         for(j=i+1;j<100;j++)
 27             if(a[i]==a[j])  a[j]='\0';
 28 
 29     for(i=0,j=0;i<100;i++)
 30         if(a[i]!='\0')  b[j++]=a[i];
 31 
 32     for(i=0;i<95;i++)
 33     {
 34         cha=' '+i;
 35         for(j=0;b[j]!='\0';j++)
 36             if(b[j]==cha)   break;
 37         if(b[j]=='\0')
 38         {   b[j]=cha; b[j+1]='\0';   }
 39     }
 40 
 41     first=p=(struct cricle *)malloc(sizeof(struct cricle));
 42     first->ch=b[0];
 43     for(i=1;i<95;i++)
 44     {
 45         p->next=(struct cricle *)malloc(sizeof(struct cricle));
 46         p=p->next;
 47         p->ch=b[i];
 48     }
 49     p->next=first;
 50     q=p;
 51     p=first;
 52 
 53     m=p->ch;
 54     que.in[0]=p->ch;
 55     que.out[94]=p->ch;
 56     q->next=p->next;
 57     free(p);
 58     p=q->next;
 59     i=1;j=0;
 60     while(p!=p->next)
 61     {
 62 
 63         if(i!=m)
 64         {
 65             q=p;
 66             p=p->next;
 67             i++;
 68         }
 69         else
 70         {
 71             que.out[j++]=p->ch;
 72             que.in[j]=p->ch;
 73             m=p->ch;
 74             q->next=p->next;
 75             free(p);
 76             p=q->next;
 77             i=1;
 78 
 79         }
 80     }
 81     que.out[93]=p->ch;
 82     que.in[94]=p->ch;
 83 
 84     if((in=fopen("in.txt","r"))==NULL)
 85         return 1;
 86     if((out=fopen("in_crpyt.txt","w"))==NULL)
 87         return 1;
 88     str=fgetc(in);
 89     while(str!=EOF)
 90     {
 91         for(i=0;i<95;i++)
 92             if(que.in[i]==str)
 93             {
 94                 fprintf(out,"%c",que.out[i]);
 95                 break;
 96             }
 97         if(i==95)
 98             fprintf(out,"%c",str);
 99         str=fgetc(in);
100     }
101     exit(0);
102     return 0;
103 }

 

转载于:https://www.cnblogs.com/tuoniao/p/10346458.html

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值