⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 维吉尼亚.cpp

📁 维吉尼亚算法的实现
💻 CPP
字号:
// P40第9题   
// 破解vigenere密码课本P15---2.3.3所用的算法   
//   
#include<stdio.h>   
#include<math.h>   
//寻找密钥长度   
int find_key_lenth(char*pass,int len)     
{   
    //pass密文,len 密文长度;移位统计相等的密文,取其最大的步数为d;   
    int d=0,count,MaxCount=0;   
    for(int step=1;step<10;step++)      //移动步数从1-10;   
    {   
        count=0;                           
        for(int j=0;j<len&&(j+step)<len;j++)   
        {   
            if(pass[j]==pass[j+step])      
                count++;   
        }   
        if(count>MaxCount)   
        {   
            MaxCount=count;   
            d=step;   
        }   
    }   
    return d;   
}   
// 发现密钥并解密。。。   
void decode(char*pass,char*ming,int d,int len)   
{   
    float v[26]={0};               // 或W向量组;   
    int per_len=len/d;             //每组长度;   
    double A[26]={0.082,0.015,0.028,0.043,0.127,              //英文字母频率表A   
              0.022,0.02,0.061,0.07,0.002,0.008,   
              0.04,0.024,0.067,0.075,0.019,0.001,   
              0.06,0.063,0.091,0.028,0.01,0.023,0.001,0.02,0.001};   
                      
    double B[26]={0};              //存储W*A值   
    char*key;                      //密钥   
    key=new char[d];     
    for(int i=0;i<d;i++)   
    {   
        int j=0;   
        while(true)                     //统计每组a--z出现的频率存在V[26]中   
        {   
            if((i+d*j)>=len) break;   
            v[pass[i+d*j]-'a']+=1;   
            j++;               
        }              
        for(int k=0;k<26;k++)          //计算W   
            v[k]=v[k]/per_len;   
  
        for(k=0;k<26;k++)              //计算B[i]=Ai*V;   
        {   
            for(int l=0;l<26;l++)         
                B[k]+=A[l]*v[(l+k)%26];        
        }   
        //找出B中的与0.065最接近的值其的下标即为密钥   
        double max=1;                       
        int c;   
        for(k=0;k<26;k++)               
        {      
            if(fabs(B[k]-0.065)<max)   
            {   
            max=fabs(B[k]-0.065);c=k;          
            }   
        }   
        key[i]=c;           
        //清空B,V;   
        for(k=0;k<26;k++)   
        {   
            B[k]=0;   
            v[k]=0;   
        }   
        printf("%c",'a'+key[i]);   
    }      
    //解密并显示   
    printf("\n\n明文:\n");   
    for(i=0;i<len;i++)   
    {   
      int tmp;   
      tmp=pass[i]-'a';   
      ming[i]=(tmp-key[i%d]+26)%26+'a';   
      printf("%c",ming[i]);   
    }    
    printf("\n\n");    
    return ;   
}   
int main()   
{   
    char password[1000]={0}; //密文   
    char mingwen[1000]={0};  //明文   
    FILE* fp;   
    if((fp=fopen("miwen.txt","r+"))==NULL)   
    {   
        printf("miwen.txt open error!\n");   
        return 1;   
    }   
    int i=0,d;   
    printf("密文:");   
    while((password[i++]=fgetc(fp))!=EOF);   
    for(int j=0;j<i;j++)   
    {   
        if(j%59==0) printf("\n");   
        printf("%c",password[j]);   
    }     
    d=find_key_lenth(password,i-1);   
    printf("\n\nd==%d\n",d);   
    printf("key=");   
    decode(password,mingwen,d,i-1);     
    fclose(fp);   
    return 0;   
}   

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -