zoukankan      html  css  js  c++  java
  • Vigenère Cipher 维吉尼亚加解密算法

    维吉尼亚的加解密有两种方法。

    第一种是查表:第一行为明文,第一列为密钥,剩余的为对应的密文


    第二种方法是转化计算法:逐个将字符转化为从零开始的数字,对数字进行加密/解密后,再转化为字符。

    本文要用c++实现第二种方法,并且为了操作方便,使用了MFC框架(附工程下载)

    核心代码如下:

    //cipher.h  额外添加的文件,用来放置相关算法,此文件独立于MFC外,可直接移植到支持CString的项目中
    int* CStringToInt(CString str){
        //将CString转换为zero_based整数
        int size=str.GetLength();
        int *asc_space=new int[size];//使用new为了返回时不被消除
        for (int i=0;i<size;i++)
        {
            asc_space[i]=int(str.GetAt(i));
            if(asc_space[i]>64&&asc_space[i]<91)        //A-Z转化
                asc_space[i]-=65;
            else if(asc_space[i]>96&&asc_space[i]<123)    //a-z转化
                asc_space[i]-=97;
        }    
        return asc_space;
    }
    
    void Encode(CString key,CString plain,CString &cipher){
        //维吉尼亚加密算法
        int *keycode=CStringToInt(key);
        int *plaincode=CStringToInt(plain);
        int *ciphercode=CStringToInt(plain);
        int keysize=key.GetLength();
        int plainsize=plain.GetLength();
        int flag=0;
        CString blank(' ',plainsize+1);    //预留一个字节放
        cipher=blank;                    //生成空白的密文
        for (int i=0;i<plainsize;i++)
        {
            if(flag>=keysize)            //轮换钥匙
                flag=0;
            ciphercode[i]=(plaincode[i]+keycode[flag])%26;    //求密文的数字码
            cipher.SetAt(i,'A'+ciphercode[i]);                //生成密文
            ++flag;
        }
        cipher.SetAt(i,'');                //在末尾放入
        delete keycode,plaincode,ciphercode;//释放CStringToInt()申请的空间
    }
    
    void Decode(CString key,CString &plain,CString cipher){
        //加密稍作修改就是解密算法
        int *keycode=CStringToInt(key);
        int *plaincode=CStringToInt(cipher);
        int *ciphercode=CStringToInt(cipher);
        int keysize=key.GetLength();
        int ciphersize=cipher.GetLength();
        int flag=0;
        CString blank(' ',ciphersize+1);    
        plain=blank;                    
        for (int i=0;i<ciphersize;i++)
        {
            if(flag>=keysize)    
                flag=0;
            //+26是为了对密文数字码小于密钥数字码的情况进行矫正
            plaincode[i]=(ciphercode[i]-keycode[flag]+26)%26;    
            plain.SetAt(i,'a'+plaincode[i]);            
            ++flag;
        }
        plain.SetAt(i,'');
        delete keycode,plaincode,ciphercode;
    }
    //MFC OnButton()响应
    void
    CVigenereCipherDlg::OnEncrypt() //加密按钮 { UpdateData(); if(m_key.IsEmpty()||m_plain.IsEmpty()) MessageBox("密钥及明文不能为空!"); else{ Encode(m_key,m_plain,m_cipher);//调用加密函数 UpdateData(false); m_ctrEDIT1.SetReadOnly(TRUE);//防止修改密钥 m_ctrEDIT2.SetReadOnly(TRUE);//防止修改明文 m_ctrEDIT3.SetReadOnly(TRUE);//防止修改密文 m_ctrEDIT4.SetReadOnly(FALSE); } } void CVigenereCipherDlg::OnDecrypt() //解密按钮 { UpdateData(); if(m_key.IsEmpty()||m_cipher.IsEmpty()) MessageBox("密钥及密文不能为空!"); else{ Decode(m_key,m_explainted,m_cipher); UpdateData(false); m_explainted=""; m_ctrEDIT1.SetReadOnly(FALSE); m_ctrEDIT2.SetReadOnly(FALSE); m_ctrEDIT3.SetReadOnly(FALSE); m_ctrEDIT4.SetReadOnly(TRUE); } }

    测试结果如下图:

    工程下载链接:

    https://files.cnblogs.com/zoffy/VigenereCipher.zip

  • 相关阅读:
    bt5设置IP
    flyCoding
    [Cocoa][译]苹果 Cocoa 编码规范中文版
    [BZOJ4569] [Scoi2016]萌萌哒
    BZOJ4899]记忆的轮廓
    [BZOJ1701] [Usaco2007 Jan]Cow School牛学校
    [Poi2011]Lightning Conductor
    [BZOJ4709] [Jsoi2011] 柠檬
    决策单调性优化dp 专题练习
    2369. 区间
  • 原文地址:https://www.cnblogs.com/zoffy/p/4022417.html
Copyright © 2011-2022 走看看