【问题标题】:C Xor Encryption (beginner)C Xor 加密(初学者)
【发布时间】:2015-02-19 10:15:38
【问题描述】:

我找到了这个用于异或加密的代码,它可以工作

string encryptDecrypt(string toEncrypt)
{
    char key = 'K'; //Any char will work
    string output = toEncrypt;
    int z = toEncrypt.size();

    for (int i = 0; i < z; i++)
    {
        output[i] = toEncrypt[i] ^ key;
    }
    return output; 
}

int main(int argc, const char * argv[])
{
    string encrypted = encryptDecrypt("kylewbanks.com");

    string decrypted = encryptDecrypt(encrypted);
    return 0;
}

但是当我把它改成这种形式时:

CHAR* encryptDecrypt(CHAR* toEncrypt)
{
     char key = 'K'; //Any char will work
     CHAR* output = toEncrypt;

     for (int i = 0; i < strlen(toEncrypt); i++)
     {
        output[i] = toEncrypt[i] ^ key;
     }
     return output;
 }

 int main(int argc, CHAR* argv[])
 {
     CHAR* encrypted = encryptDecrypt("kylewbanks.com");
     CHAR* decrypted = encryptDecrypt(encrypted);
     return 0;
 }

程序中断并显示此消息:访问冲突写入位置 0x001CCC90

我的变量需要使用 CHAR* 或 WCHAR*(我没有使用字符串的权限)

问题是:

1- 第二个代码有什么问题?

2- 如何将键更改为单词而不是字符?

感谢您的帮助:)

编辑:

问题是它在第 7 行之后立即中断

它根本不做这行:

output[i] = toEncrypt[i] ^ key;

【问题讨论】:

  • string 不是标准的 C 类型,因此您的问题不容易重现。你确定这不是 C++,还是应该包含一些非标准的头文件?
  • 我在我的问题中说我没有使用字符串的权限,我找到了一个 C++ 代码,但我必须编写一个 C 代码。这是我的问题...
  • 这一行CHAR* encrypted = encryptDecrypt("kylewbanks.com"); 试图更改一个只读 字符串(我怀疑string 声明在原文中屏蔽了你)。见stackoverflow.com/questions/1455970/cannot-modify-c-string

标签: c


【解决方案1】:

1、在encryptDecryptoutput是一个局部变量并链接到一个静态字符串区域,它是只读的。通常你需要创建一个缓冲区空间并将其传递给encryptDecrypt。函数内部的malloc 也可以,但您需要手动free。顺便说一句,strlen 也很危险,因为加密的数据可能不是有效的字符串。

2,使用WCHARwcslen 代替CHARstrlen,使用L'k' 键应该可以工作。

【讨论】:

  • 我也更新了答案,用手机编辑很慢,抱歉。
【解决方案2】:

1- 第二个代码有什么问题?

据我了解,您想加密和解密一个 c 字符串。 C 中的字符串通常是字符数组,并以 0 结尾。另外你在这里使用了错误的指针算法。

同时:

string output = toEncrypt;

对整个字符串进行复制操作,

CHAR* output = toEncrypt;

只会创建一个新指针并让它指向指针toEncrypt指向atm的同一点。所以最后你只有 2 个指针指向同一个位置,这和使用 1 个指针一样好。

我建议您在该方法中创建一个新缓冲区来存储加密数据:

CHAR* output = new CHAR[strlen(toEncrypt)];

虽然如果您不加密以零结尾的字符串,这可能会导致未定义的行为。因为strlen 会继续计数字符,直到找到0。因此,我还建议您将要加密的数据长度发送到您的函数:

CHAR* encryptDecrypt(CHAR* toEncrypt, int length)

另外,只读字符初始化在 C 中始终是常量。

所以一个可能的解决方案是:

wchar_t* encryptDecrypt(const wchar_t* toEncrypt, int length)
{
    wchar_t key = L'K'; //Any char will work
    wchar_t* output = new wchar_t[length];  // Make a temporary buffer

    for (int i = 0; i < length; i++)
    {
        output[i] = toEncrypt[i] ^ key; // Encrypt every char of the array to encrypt
    }
    return output;
}

int main(int argc, CHAR* argv[])
{
    // Your Data to encrypt / decrypt
    const wchar_t* sourceString = L"kylewbanks.com";
    const int sourceStrLen = wcslen(sourceString); // Get the lenght of your data before you encrypt it and can't use wcslen anymore. Alternatively just enter the amount of characters in your string here.

    // Encrypt / Decrypt your String
    wchar_t* encrypted = encryptDecrypt(sourceString, sourceStrLen);
    wchar_t* decrypted = encryptDecrypt(encrypted, sourceStrLen);

    // Free the allocated buffers
    delete[] encrypted;
    delete[] decrypted;

    return 0;
}

请注意,如果您想使用 printf() 之类的方法在某处显示此字符串,它可能会在您的字符串之后显示一些内存垃圾,因为加密仅返回加密数据,不是零终止.

2- 如何将键更改为单词而不是字符?

您可以使用多种方法对键字符串进行异或运算,但最简单的方法之一是将源字符串与键字符串反复异或。

类似:

    kylewbanks.com
XOR keykeykeykeyke
__________________
    RESULT

如果您的密钥字符串是“key”

可能的解决方案:

wchar_t* encryptDecrypt(const wchar_t* toEncrypt, int length)
{
    const wchar_t* key = L"KEY"; // A readonly wide String
    wchar_t* output = new wchar_t[length];  // Make a temporary buffer

    for (int i = 0; i < length; i++)
    {
        output[i] = toEncrypt[i] ^ key[i % wcslen(key)];    // i % 3 wil be ascending between 0,1,2
    }
    return output;
}

【讨论】:

  • 谢谢,这段代码有效,请回答第二个问题好吗?我想用一个词而不是一个字符来异或,wchar_t* key = L"prtas"
  • @user3105142 好的,我用您的第二个问题的解决方案更新了答案。我希望它有帮助:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-12
  • 2014-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多