微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么我的小写字母 Vigenere 加密功能无法正常工作?

如何解决为什么我的小写字母 Vigenere 加密功能无法正常工作?

我尝试过实施 Vigenere 的 Cypher。我发现它与大写字母一起使用,但我已将其用于大写和小写字母,但纯文本或密码文本的字符必须与密钥中的相应字符相同。所以我这样做了:

std::string encryptUpper(std::string const& plain,std::string const& key){
    std::string cyphered;
    for(std::size_t i = 0,j = 0,plainLen = plain.length(),keyLen = key.length();
        i != plainLen; ++i,++j){
        if(j == keyLen)
            j = 0;
        cyphered += ( (plain.at(i) + key.at(j) ) % 26) + 'A';
    }
    return cyphered;
}

std::string decryptUpper(std::string const& cyphered,std::string const& key){
    std::string plain;
    for(std::size_t i = 0,cypheredLen = cyphered.length(),keyLen = key.length();
        i != cypheredLen; ++i,++j){
        if(j == keyLen)
            j = 0;
        plain += ( ( (cyphered.at(i) - key.at(j) + 26) % 26) + 'A');
    }
    return plain;
}

std::string encryptLower(std::string const& plain,++j){
        if(j == keyLen)
            j = 0;
        cyphered += ( (plain.at(i) + key.at(j) ) % 26) + 'a';
    }
    return cyphered;
}

std::string decryptLower(std::string const& cyphered,++j){
        if(j == keyLen)
            j = 0;
        plain += ( (cyphered.at(i) - key.at(j) + 26 ) % 26) + 'a';
    }
    return plain;
}


std::string encrypt(std::string const& plain,++j){
        if(j == keyLen)
            j = 0;
        cyphered += ( (plain.at(i) - (std::isupper(plain.at(i)) ? 'A' : 'a') + key.at(j) - (std::isupper(plain.at(i)) ? 'A' : 'a') ) % 26) +
        (std::isupper(plain.at(0)) ? 'A' : 'a');
    }
    return cyphered;
}

std::string decrypt(std::string const& cyphered,++j){
        if(j == keyLen)
            j = 0;
        plain += ( (cyphered.at(i) - key.at(j) + 26 ) % 26) +
        (std::isupper(cyphered.at(i)) ? 'A' : 'a');
    }
    return plain;
}

int main(){

    std::string s1 = "HELLO";
    std::string key1 = "ATOM";
    auto cyphered1 = encryptUpper(s1,key1);
    std::cout << cyphered1 << '\n';
    auto plain = decryptUpper(cyphered1,key1);
    std::cout << plain << '\n';

    std::string s2 = "hello";
    std::string key2 = "atom";

    auto cyphered2 = encryptLower(s2,key2);
    std::cout << cyphered2 << '\n';
    auto plain2 = decryptLower(cyphered2,key2);
    std::cout << plain2 << '\n';

    cyphered2 = encrypt(s2,key2);
    std::cout << cyphered2 << '\n';
    plain2 = decryptLower(cyphered2,key2);
    std::cout << plain2 << '\n';

    std::cout << "=========\n";
    auto c1 = encrypt(s1,key1);
    auto p1 = decrypt(c1,key1);
    std::cout << c1 << '\n' << p1 << '\n';

    auto c2 = encrypt(s2,key2);
    auto p2 = decrypt(c2,key2);
    std::cout << c2 << '\n' << p2 << '\n';
}
  • 为什么 encryptLower()错误的方式加密小写文本?虽然我们知道规则是:

    Ei = (Pi + Ki) mod 26
    

和解密:

  Di = (Ei - Ki + 26) mod 26
  • 为什么在加密小写字母时,我需要从密钥和纯文本字符中减去 a 的值,然后求和和 mod 26?为什么我不需要大写字母?

  • 我的通用 encrypt()decrypt 函数是否正确?谢谢!

  • 我确定问题出在这里

      char P = 'H'; // 72
      char K = 'A'; // 65
    
      char C = (P + K) % 26; // 7
      C += 'A'; // 7 + 'A' =  H
      std::cout << C << '\n'; // H
    
      char p = 'h'; // 104
      char k = 'a'; // 97
    
      char c = (p + k) % 26; // 19
      c += 'a'; // 19 + 'a' = t
      std::cout << c << '\n'; // t
    
  • 通常使用键 aA 会产生与大写字母相同的密码字符,但为什么不能使用小写字母?

解决方法

考虑 Ascii 表:http://www.asciitable.com/。 如果您将字符写为 (65+i)(65+j) 并使用大写方法添加它们,您将得到 65+(65+i)+(65+j) \equiv 65+i+j \mod 26。 您很幸运,65 + 65 可以被大写的 26 整除!

对于小写字母,我们没有可以被 26 整除的 97+97

在 SO 上调试和发布代码的一些提示:您的代码输出在方法的第一个字母中是错误的,所以那里出了点问题。如果你只考虑这个最小的例子,就更容易发现错误。因此,请尝试生成一个可重现的最小示例。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。