普莱菲尔密码

根据普莱菲尔密码规则对明文进行加密。

分别有三个文件:明文、密码、密文,分别在文件中输入明文和密码,加密后将会储存在密文的文件中,

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int lenw,lenm;
char mw[1000],mm[26];//明文,密码
char clw[2000];//最终的密文
int len;
char a[6][6];//密码表
char x[26];//密码替换表
char b[1000][2];//明文表
FILE *ch;

bool start()
{
    int i;
    ch=fopen("明文.txt","r");
    if(ch==NULL)
    {
        printf("明文打开出错\n");
        return 0;
    }
    fgets(mw,1000,ch);
    lenw=strlen(mw);
    mw[lenw]=' ';

    ch=fopen("密码.txt","r");
    if(ch==NULL)
    {
        printf("密码打开出错\n");
        return 0;
    }
    fgets(mm,100,ch);
    lenm=strlen(mm);
    mm[lenm]=' ';

    char j='a';
    int k=0;
    bool t[26];//字母是否出现过
    memset(t,0,sizeof(t));
    t[25]=1;//z默认标记为已用

    for(i=0; i<lenm; i++) //去重
    {
        if(!t[mm[i]-'a'])
        {
            mm[k]=mm[i];
            t[mm[i]-'a']=1;
            k++;
        }
    }

    for(i=k; i<100; i++)//后面接字母
    {
        while(t[j-'a'])//有重复的跳过
            j++;
        mm[i]=j;
        j++;
        if(j=='z')//发现j=='z'重置
            j='a';
    }
    return 1;
}

void ps_list()//打二维表
{
    int i,j,k=0;
    for(j=0; j<5; j++)//mm数列里已经没有z
    {
        for(i=0; i<5; i++)
        {
            a[i][j]=mm[k];
            k++;
        }
    }
}

void op_word()
{
    int i=0,j=0;
    if(mw[i]==mw[i+1]||(!j%2&&mw[i+1]==mw[i+2]))
    {
        clw[j]=mw[i];
        j++;
        clw[j]='x';
        j++,i++;
    }
    else
    {
        clw[j]=mw[i];
        j++,i++;
    }
    for(; i<1000; )
    {
        if(i>=lenw)//明文遍历结束
            break;
        if(mw[i]==mw[i+1]||mw[i]==mw[i-1]||(!j%2&&mw[i+1]==mw[i+2]))//是否前后有相同,或者是单个字母
        {
            clw[j]=mw[i];
            j++;
            clw[j]='x';
            j++,i++;
        }
        else
        {
            clw[j]=mw[i];
            j++,i++;
        }
    }
    len=j;
    if(!j-1%2)//判断末端是否为单个字母
    {
        clw[j]='x';
        len=j+1;
    }
}

int x1,x2,y1,y2;
void getw(char x,char y)//获取这两个字母在表中的坐标
{
    int i,j;
    for(i=0; i<5; i++)
        for(j=0; j<5; j++)
        {
            if(a[i][j]==x)
            {
                x1=i;
                y1=j;
            }
            if(a[i][j]==y)
            {
                x2=i;
                y2=j;
            }
        }
}

void end_word()
{
    int i,x,y;
    for(i=0; i<len; i+=2)//按规则两两替换处理后的明文
    {
        getw(clw[i],clw[i+1]);
        if(x1!=x2&&y1!=y2)
        {
            clw[i]=a[x1][y2];
            clw[i+1]=a[x2][y1];
        }
        else if(x1==x2)
        {
            x=x1,y=y1+1;
            if(y==5)
            y=0;
            clw[i]=a[x][y];

            x=x2,y=y2+1;
            if(y==5)
            y=0;
            clw[i+1]=a[x][y];
        }
        else if(y1==y2)
        {
            x=x1+1,y=y1;
            if(y==5)
            y=0;
            clw[i]=a[x][y];

            x=x2+1,y=y2;
            if(y==5)
            y=0;
            clw[i+1]=a[x][y];
        }
    }
}


int main()
{
    int n,m,i,j;
    if(!start())//文本获取
        return 0;

    ps_list();//编制密码表
    op_word();//整理明文
    end_word();//编写密文
    for(i=0;i<len;i++)
    printf("%c",clw[i]);
    ch=fopen("密文.txt","w");
    if(ch==NULL)
    {
        printf("密文打开出错\n");
        return 0;
    }
    fwrite(clw,len,sizeof(char),ch);
    fclose(ch);
    printf("\n");
    getchar();
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值