首    页 界面/窗口 网络/通讯 数据库 组件开发 图像/多媒体 NET/Web 其它技术 源码下载 资料下载 软件共享 软件外包 曲艺杂谈
栏目导航:  首    页  |  其它技术  |  加密解密  


恺撒加密与解密小程序


原作者:kvew    源出处:smatrix   发布者:施昌权    发布类型:转载    发布日期:2008-12-02


作者:kvew        www.smatrix.org

先简单介绍下恺撒加密法,是一个很古老也很简单的加密方法,就是把信息中的字母右移N位,产生密文,比如"Z" 右移2位后为"B"。关于解密用到了一个统计规律,在大量的文献中字母"E"的出现频率是最高的,那么对于用该算法加密的文件,我们只要统计出密文中出现频率最高的字母,然后和"E"比较下,就能得出密钥key。当然好有很多改进的方案,比如两个字母的单词出现频率高的"IS",三个字母的单词"THE"出现的比较多等等。我这里只是简单实现一下加密解密,没有涉及到算法改进,甚至这个程序也会有某些问题,如果您能提出来,那真的是非常感谢了!
先说一下输入测试信息的规则,由于前面说到,求解密钥用的是"E"出现频率最高这点,所以在输入要加密的信息时人为的多写点E进去,大写小写的都无所谓!如果感兴趣,可以把该程序梢加修改,用于加密一篇英文文章,然后用解密函数解密。

源程序如下:

简单介绍下,这里只对字母加密,其他符号没有进行加密。定义char类型的时候定义为unsigned char,如果不定义为无符号类型的话,在对小写字母移位较大的情况下,其ASCII码值会超过127,这样就会出现异常。

#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
char    kaiser(int n){
       unsigned char ch;

       ch = getchar();

        if(ch>=65&&ch<=90){  //如果是大写字母
            ch = ch + n;      //移位
            if(ch<91)         //移位后仍然在大写字母集中,直接返回
                return ch;
            else
                return ch%90+64;   //超出则转换下
        }

        else if(ch>=97&&ch<=122){    //如果是小写字母
            ch = ch + n;               //移位
            if(ch<123)                   //移位后仍然在小写字母集,直接返回
                return ch;
            else
                return ch%122+96;     //超出则转换下
           
   }

        return ch;                      //如果是其他字符,则不加密照常输出
}

 

void    write_file(){                //写文件函数
   
    int     n ;
    unsigned char    ch = 65 ;                //先随便给个初始值,后面要用到它判断输入是否结束
    FILE    *fp;

    if((fp = fopen("a.txt","w"))==NULL){        // 判断fopen的返回值,打开文件是否成功
        printf("Error,can't open the file!\n");
        exit(0);
    }

    printf("please input the key (0--25):\n");
    scanf("%d",&n);
  if(n<0||n>25){
   printf("Error! Wrong key number!\n");
   exit(0);
  }

 
    printf("Please input the file end with $\n");
    while(ch!=36 ){    //如果成功,向里面写入,以 $ 结束
 
        ch = kaiser(n);    //把输入字符用kaiser加密法加密
        fputc(ch,fp);
    }
   
    if(fclose(fp)){
        printf("Can not close the file!\n");
   
    }
}


   

void    break_kaiser(){

        int     i,count,k;
        int     key;
        int     num[26] = {0};          //初始化数组
        unsigned  char    ch,ch_b;
        FILE    *fp1,*fp2;

        if((fp1=fopen("a.txt","r"))==NULL){  //以读的方式打开文件a.txt
            printf("can not open the file a.txt!\n");
            exit(0);
        }

        if((fp2=fopen("b.txt","w"))==NULL){   //以写的方式打开b.txt
            printf("can not open the file b.txt!\n");
            exit(0);
        }

        while(!feof(fp1)){
            ch = fgetc(fp1);
            printf("the ch in a.txt is:%c\n",ch);      //这行可以注释掉,是显示读取细节的东西
                if(ch>=65&&ch<=90){
                    num[ch-65]++;
                printf("the num[%d] is %d\n",ch-65,num[ch-65]);   //同上,可以注释掉
                }

                else if(ch>=97&&ch<=122){
                    num[ch-97]++;
                printf("the num[%d] is %d\n",ch-97,num[ch-97]);  //同上
                }
        }

        if(fclose(fp1)){                     //关闭目标文件a.txt
            printf("Can not close the file!\n");
   
        }

        count = num[0];
        for(i=0;i<26;i++){
            printf("the num[%d] is %d\n",i,num[i]);
            if(count<num[i]) {
                count = num[i];    
                k   = i;    //记录下最大值的下标   
            }
        }
       
                
        printf("the max is %d  and its index is %d\n",count,k);
        ch_b  = 65 + k;             // 记录下出现次数最多的字符,以大写方式记录
        key   = ch_b - 69;        //和 E 值相减,计算出key
   if(key<0)
    key = 26 + key;
   
        printf("the key is: %d\n",key);
        if((fp1=fopen("a.txt","r"))==NULL){  //再次以读的方式打开文件a.txt
            printf("can not open the file a.txt!\n");
            exit(0);
        }
       
       
        while(!feof(fp1)){   //如果没有读到文件结尾,那么继续读取
            ch = fgetc(fp1);
              
                if(ch>=65&&ch<=90){
                    ch = ch - key;

                    if(ch < 65)
                        ch = 90 - (64 - ch);
                   
                }

                if(ch>=97&&ch<=122){
                    ch = ch - key;

                    if(ch < 97)
                        ch = 122 - (96 - ch);
                }

           
                fputc(ch,fp2);
        }

        if(fclose(fp2)){                     //关闭文件b.txt
            printf("Can not close the file!\n");
   
        }
}

 

int main(){


    write_file();

    break_kaiser();
    return 0;
}

改进恺撒加密与解密小程序

把昨天写的那个恺撒加密解密的简单木模拟程序稍微改了下,对目标文件 a.txt 加密,然后生成密文 kaiser.txt,接着对其解密,生成 out.txt。
 
在程序输出过程中,把密文中的各个字母的统计信息也打印出来了,数组元素num[0]----num[25]对应与字母A---Z。
 
以下程序在VC6.0下编译通过。
 
源程序:
// 恺撒加密解密小程序
// 作者:kvew    www.smatrix.org
//
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
void   kaiser(int n){
       unsigned char ch;
        FILE *fp1,*fp2;
        if((fp1=fopen("a.txt","r"))==NULL){  //以读的方式打开文件a.txt
            printf("can not open the file a.txt!\n");
            exit(0);
        }
        if((fp2=fopen("kaiser.txt","w"))==NULL){   //以写的方式打开b.txt
            printf("can not open the file b.txt!\n");
            exit(0);
        }
        while(!feof(fp1)){
        ch = fgetc(fp1);
        if(ch>=65&&ch<=90){  //如果是大写字母
            ch = ch + n;      //移位
            if(ch>=91)         //移位后仍然在大写字母集中,直接返回
               ch = ch%90+64;   //超出则转换下
        }
        else if(ch>=97&&ch<=122){    //如果是小写字母
            ch = ch + n;               //移位
            if(ch>=123)                   //移位后仍然在小写字母集,直接返回
                ch = ch%122+96;     //超出则转换下
            }
        fputc(ch,fp2);                          //如果是其他字符,则不加密照常输出
        }
           if(fclose(fp1)){                     //关闭文件a.txt
            printf("Can not close the file!\n");
   
        }
              if(fclose(fp2)){                     //关闭文件kaiser.txt
            printf("Can not close the file!\n");
   
        }
}
 
void    break_kaiser(){
        int     i,count,k;
        int     key;
        int     num[26] = {0};          //初始化数组,该数组用来统计密文中各个字母的出现次数
        unsigned  char    ch,ch_b;      // num[0]-----num[25]对应字母A--Z
        FILE    *fp1,*fp2;

        if((fp1=fopen("kaiser.txt","r"))==NULL){  //以读的方式打开文件a.txt
            printf("can not open the file a.txt!\n");
            exit(0);
        }
        if((fp2=fopen("out.txt","w"))==NULL){   //以写的方式打开b.txt
            printf("can not open the file b.txt!\n");
            exit(0);
        }
        while(!feof(fp1)){
            ch = fgetc(fp1);
                    if(ch>=65&&ch<=90){
                    num[ch-65]++;
                       }
                else if(ch>=97&&ch<=122){
                    num[ch-97]++;
                       }
        }
        if(fclose(fp1)){                     //关闭目标文件a.txt
            printf("Can not close the file!\n");
   
        }
        count = num[0];
        for(i=0;i<26;i++){
            printf("the num[%d] is %d\n",i,num[i]); //打印出统计信息
            if(count<num[i]) {
                count = num[i];    
                k   = i;    //记录下最大值的下标   
            }
        }
       
                
        printf("\n\nthe max is %d  and its index is %d\n",count,k);
        ch_b  = 65 + k;             // 记录下出现次数最多的字符,以大写方式记录
   printf("the ch_b is %d\n",ch_b);
        key   = ch_b - 69;        //和 E 值相减,计算出key
        if(key<0)
            key = 26 + key;
   
        printf("the key is: %d\n",key);
        if((fp1=fopen("kaiser.txt","r"))==NULL){  //再次以读的方式打开文件a.txt
            printf("can not open the file a.txt!\n");
            exit(0);
        }
       
       
        while(!feof(fp1)){   //如果没有读到文件结尾,那么继续读取
            ch = fgetc(fp1);
              
                if(ch>=65&&ch<=90){
                    ch = ch - key;
                    if(ch < 65)
                        ch = 90 - (64 - ch);
                   
                }
                if(ch>=97&&ch<=122){
                    ch = ch - key;
                    if(ch < 97)
                        ch = 122 - (96 - ch);
                }
           
                fputc(ch,fp2);
        }
        if(fclose(fp2)){                     //关闭文件b.txt
            printf("Can not close the file!\n");
   
        }
}
 
int main(){
    int n;
 
   
    printf("***********************************************************\n");
    printf("*                                                                                               *\n");
    printf("* this program will encrypt the file a.txt to kaiser.txt!      *\n");
    printf("* and then decrypt kaiser.txt to out.txt                                *\n");
    printf("*                                                                                               *\n");
    printf("***********************************************************\n\n");
   
 printf("\nplease input the key number (0--25):\n");
    scanf("%d",&n);
 
  kaiser(n);
 printf("encrypted success!\n\n"); 
// printf("密文中各字母出现次数的统计信息入下:\n");
 
    break_kaiser();
 printf("creaked success!\n");
    return 0;
}

程序有很多不成熟的地方,如果有朋友能提出来的话,非常感谢了:)


关于我们 版权声明 广告服务 联系我们 友情链接 加入收藏
站长:施昌权    Email:scq2099yt@163.com    MSN:scq2099yt@live.cn    QQ:14046300    本站QQ群:67202409
Copyright © 2008     卓为VC(www.joyvc.cn)    All Rights Reserved    建议分辨率 1024×768
本站由施昌权制作维护
京ICP备09012297号