在 C++ 中使用字符向量来编写凯撒密码

Using a vector of characters in C++ to program a Caesar Cipher

我一直在编写一段代码,使用凯撒密码对消息进行加密。我尽量保持简单。

/* 
 * File:   main.cpp
 * Author: Skylar Croy
 *
 * Created on February 10, 2015, 11:50 AM
 * 
 * Purpose: To encrypt a message using the Caesar Cipher 
 */

#include <iostream>
#include <vector>
#include <string>

using namespace std;
int main(int argc, char *argv[]) {

    char letters[] = 
    {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}; // Make a vector, letter, which equals [a b c ... z]
    int i, k; // i used in two loops, k used for shift 3 and mod calc

    for (i=0; i<=25; i++) { // Run 26 times (1 for each letter)

        k = (i + 3) % 26; // Performs mod arth. with shift of 3

        letters[i+26] = letters[k]; // letter[i+26] = [d e f g ... c]
        // Note that letters = [a b c ... z d e f g....c]
             /* cout << letters[i]; // This code shows that the operation in this for loop is functioning correctly
                cout << " ";
                cout << letters[i+26];
                cout << " \n"; */          
    }

    std:: string x; // declare string x
    cin >> x; 

        int string_length = x.size();

    for (i=0; i<=(string_length-1); i++){ // individual characters of string x can be referenced by x[0] etc

        for (k=0; k<=25; k++){ 

            if (x[i] == letters[k]) {

                            cout << letters[k+26];

            }
        }
    } 
return 0;
}

出于某种原因,当您尝试使用 w、x、y 或 z 加密邮件时,它不起作用并打印随机垃圾。不知道哪里出了问题。任何意见将是有益的。谢谢

我还没有读完你的代码,但下面一行肯定是越界的:

letters[i+26] = letters[k]; // letter[i+26] = [d e f g ... c]

您的 letters 数组只有 26 长,但您正在访问第 i+26 个元素。也许试试:

letters[(i+26)%26] = letters[k]; // letter[i+26] = [d e f g ... c]

您绝对不应该尝试在数组范围之外赋值!

同样,当您打印信件时:

cout << letters[k+26];

您将超出数组的范围,这意味着您将打印垃圾...

这可能不是全部错误,但这是一个开始...

还有一个提示(除了上面提到的写数组之外)——你不能像那样做替换:

letters[i] = letters[k];

因为您会覆盖现有项目。也许更简单更好的选择是使用另一个数组来创建修改后的字母表?

char new_letters = new char[26]; for (int i=0; i<26; i++) new_letters[i] = letters[(i+3) % 26];

并使用新数组进行编码:

if ('a' - x[i] < 26) cout << new_letters['a'-x[i]];

这将只替换小写字母

其他回答已经指出了您原来尝试的错误。我只想说你的目标可以在两行内实现:

for (auto& each : x)    // where x is your std::string
    each = (each - 'a' + 3) % 26 + 'a';

@nonsensickle 是正确的。只需为加密向量制作另一个长度为 26 的向量即可修复它。谢谢!

下面的代码有效:

/* 
 * File:   main.cpp
 * Author: Skylar Croy
 *
 * Created on February 10, 2015, 11:50 AM
 * 
 * Purpose: To encrypt a message using the Caesar Cipher 
 */

#include <iostream>

using namespace std;
int main(int argc, char *argv[]) {

    char letters[] = 
    {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}; // Make a vector, letter, which equals [a b c ... z]
    int i, k; // i used in two loops, k used for shift 3 and mod calc
    char letters_cipher[25];

    for (i=0; i<=25; i++) { // Run 26 times (1 for each letter)

        k = (i + 3) % 26; // Performs mod arth. with shift of 3

        letters_cipher[i] = letters[k]; // letter[i+26] = [d e f g ... c]
        // Note that letters = [a b c ... z d e f g....c]
        /*
        cout << letters[i]; // This code shows that the operation in this for loop is functioning correctly
        cout << " ";
        cout << letters[i+26];
        cout << " \n";
        */          
    }

    std:: string x; // declare string x
    cin >> x; 

    int string_length = x.size();

    for (i=0; i<=(string_length-1); i++){ // individual characters of string x can be referenced by x[0] etc
        for (k=0; k<=25; k++){ 
            if (x[i] == letters[k]) {
                cout << letters_cipher[k];
            }
        }
    }

    return 0;
}