在我的文本编码器程序中找不到错误
Can't find the error in my text encoder program
只是为了好玩,我一直在研究一个文本编码程序,它将对文本进行加扰。我让它几乎完美地工作,但似乎无法解决一个错误。基本上,文本大部分都会正确编码和解码,除了偶尔,程序会解码字符串中有一个字母错位。代码有点难看,我还没有尝试清理它,因为我还在解决这些错误,所以我很抱歉。它在各个部分的复制和粘贴也很糟糕,所以在我让它正常工作之后,优化的机会对我来说是巨大的。我有一种感觉,我知道错误在哪里,但是进行我认为需要进行的更正会导致无限循环。这是代码,底部有一些输出存储在注释中:
#include <iostream>
using namespace std;
void FillKey(char Key2[]);
void Encrypt();
void EncryptMessage(char Key3[], char Input2[], char MessageEncrypted2[]);
void Decrypt();
void DecryptMessage(char Key4[], char CodedInput2[], char NormalOutput2[]);
char ReturnDecodedCharacter(char Key5[], char Character);
const int STRING_SIZE=500;
const int ASCII_RANGE_SIZE_94=94;//Range from ASCII value 32 to 126 = 94
const int SHIFT_SET_32=32;//Move range up 32 values form (0-93) to (32 to 126)
int main()
{
int Choice;
do
{
cout << "Press 1 to encrypt" << endl;
cout << "Press 2 to decrypt" << endl;
cout << "Press other key to quit" << endl << endl;
cout << "Choice: ";
cin >> Choice;
if (Choice == 1)
Encrypt();
else if (Choice == 2)
Decrypt();
}
while (Choice==1 || Choice == 2);
}
void Encrypt()
{
int SecretNumber;
char Key[ASCII_RANGE_SIZE_94]={0};//One larger 0 - 93, not using 0
char Input[STRING_SIZE]={0};
char MessageEncrypted[STRING_SIZE]={0};
cout << "\nEnter Secret Number: ";
cin >> SecretNumber;
cin.ignore(1);//removes newline from input buffer
srand(SecretNumber);//Seed number for my random number generator
FillKey(Key);
cout << "\nInput message: ";
cin.getline(Input, STRING_SIZE);
EncryptMessage(Key, Input, MessageEncrypted);
cout << "\nEncrypted Message(copy inside of parenthesis): " << "(" << MessageEncrypted << ")" << endl << endl;
}
void FillKey(char Key3[])
{
int RandomNumber;
int KeySpot, j;
for (KeySpot=0; KeySpot<=ASCII_RANGE_SIZE_94; ++KeySpot)
{
RandomNumber = SHIFT_SET_32+rand()%ASCII_RANGE_SIZE_94;//0-93, then shifts up to 32-126 ASCII range
for (j=0; j<=KeySpot; ++j)//this bit of code checks to make sure new rand number isn't already used before
{
if (Key3[j] == RandomNumber)
{
RandomNumber = SHIFT_SET_32+rand()%ASCII_RANGE_SIZE_94;//0-93, then shifts up to 32-126
j=0;
}
}
Key3[KeySpot] = (char) RandomNumber;
}
}
void EncryptMessage(char Key3[], char Input2[], char MessageEncrypted2[])
{
for (int i=0; Input2[i]; ++i)
{
MessageEncrypted2[i]= Key3[((int) Input2[i])-SHIFT_SET_32];//-32 to get range back into 1-95 (range of Key)
}
}
void Decrypt()
{
int SecretNumber;
char Key[ASCII_RANGE_SIZE_94]={0};
char EncryptedMessage[STRING_SIZE]={0};
char DecodedMessage[STRING_SIZE]={0};
cout << "\nEnter Secret Number: ";
cin >> SecretNumber;
cin.ignore(1);//removes newline from input buffer
srand(SecretNumber);//Seed number for random number generator
FillKey(Key);
cout << "\nInput message to decode: ";
cin.getline(EncryptedMessage, STRING_SIZE);
DecryptMessage(Key, EncryptedMessage, DecodedMessage);
cout << "\nDecoded Message: " << DecodedMessage << endl << endl;
}
void DecryptMessage(char Key4[], char EncryptedMessage2[], char DecodedMessage2[])
{
for (int i=0; EncryptedMessage2[i]; ++i)
{
DecodedMessage2[i] = ReturnDecodedCharacter(Key4, EncryptedMessage2[i]);
}
}
char ReturnDecodedCharacter(char Key5[], char Character)
{
for (int Count=0; Count<=ASCII_RANGE_SIZE_94; ++Count)
{
if ((int) Character == Key5[Count])
{
return (char) Count+SHIFT_SET_32;//+32 to get back into 32-126 ASCII range
}
}
return 0;
}
/*
Press 1 to encrypt
Press 2 to decrypt
Press other key to quit
Choice: 2
Enter Secret Number: 1
Input message to decode: abcdefghijklmnopqrstuvqwyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
Decoded Message: Yj.63;nQb_ d"*!yTuc'8rTWi~1/|^ta5:?s+ODJwge42X,%q$SEvNZ9-h=kFL
Press 1 to encrypt
Press 2 to decrypt
Press other key to quit
Choice: 1
Enter Secret Number: 2
Input message: abcdefghijklmnopqrstuvqwyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
Encrypted Message(copy inside of parenthesis): (oZs?=LtFPSk<B +j]&xf!}]1"yq;zQm8\:>|T7_56VRH{9D-/*aOdbGCgAnJuv)
Press 1 to encrypt
Press 2 to decrypt
Press other key to quit
Choice: 2
Enter Secret Number: 2
Input message to decode: oZs?=LtFPSk<B +j]&xf!}]1"yq;zQm8\:>|T7_56VRH{9D-/*aOdbGCgAnJuv
Decoded Message: abcdefghijklmnopqrstuvqwyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
Press 1 to encrypt
Press 2 to decrypt
Press other key to quit
Choice: 1
Enter Secret Number: 3
Input message: abcdefghijklmnopqrstuvqwyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
Encrypted Message(copy inside of parenthesis): (w?oGY`hn5Ty% L\Z$qrDHR$"!F=WX}IV-Nf|g&+(Ps.pM*S)1t/e2@9v067{KC)
Press 1 to encrypt
Press 2 to decrypt
Press other key to quit
Choice: 2
Enter Secret Number: 3
Input message to decode: w?oGY`hn5Ty% L\Z$qrDHR$"!F=WX}IV-Nf|g&+(Ps.pM*S)1t/e2@9v067{KC
Decoded Message: abcdefghijklmnopqrstuvqwyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
Press 1 to encrypt
Press 2 to decrypt
Press other key to quit
Choice: 1
Enter Secret Number: 4
Input message: abcdefghijklmnopqrstuvqwyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
Encrypted Message(copy inside of parenthesis): (2RQ%?u*"_yNXs!=t;VWb9);]:+#>dqv$wU7(EiP[JgGI&pxmh4\ eafk}0^1ln)
Press 1 to encrypt
Press 2 to decrypt
Press other key to quit
Choice: 2
Enter Secret Number: 4
Input message to decode: 2RQ%?u*"_yNXs!=t;VWb9);]:+#>dqv$wU7(EiP[JgGI&pxmh4\ eafk}0^1ln
Decoded Message: bcdefghijklmnopqrstuvqwyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
Press 1 to encrypt
Press 2 to decrypt
Press other key to quit
Choice:
*/
如果您注意到,最后一个字符串(密码为 4)没有正确转换并丢失了初始 'a'。我认为错误出在 void FillKey
函数中 - 在 if 语句中 if (Key3[j] == RandomNumber)
我创建了一个新的随机数并设置 j=0
如果任何新生成的随机数与之前的随机数完全相同键中的那些(显然不能两次使用相同的字符)。所以我的想法是,j 被设置为 0,但在 for 循环之后,它递增并变为 1。所以程序不检查 Key3[3]
中的重复项,所以我将语句更改为 j=-1
,预测它并在 for 循环后将其归零,但随后程序卡住并且永远不会存在循环。
如有任何建议,我们将不胜感激。
这里有错误:
for (KeySpot=0; KeySpot<=ASCII_RANGE_SIZE_94; ++KeySpot)
应该是:
for (KeySpot=0; KeySpot < ASCII_RANGE_SIZE_94; ++KeySpot)
因为密钥大小是 ASCII_RANGE_SIZE_94
,其中包括零索引。同样的错误在ReturnDecodedCharacter
,应该是:
for (int Count=0; Count < ASCII_RANGE_SIZE_94; ++Count)
为了让代码更易读,可以这样写:
char ReturnDecodedCharacter(const char *key, int keysize, char Character)
{
for (int Count = 0; Count < keysize; ++Count)
{
if (Character == key[Count])
{
return (char)(Count + SHIFT_SET_32);//+32 to get back into 32-126 ASCII range
}
}
return 0;
}
然后在调用函数时将ASCII_RANGE_SIZE_94
作为keysize
传递
这也可以用 XOR 运算符来完成
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
void xor_with_cipher(const string &cipher, const string &src, string &dst)
{
for (unsigned int i = 0; i < src.length(); i++)
{
char c = src[i] ^ cipher[i];
dst.push_back(c);
}
}
int main()
{
string cipher;
//create a simple cipher key with rand()
//Note, rand **** should not **** be used in real cryptography applications
int secretKey = 123;
srand(secretKey);
for (int i = 0; i < 100; i++)
{
char c = rand() % 0xff;
cipher.push_back(c);
}
string input = "plain text";
string encoded;
string decoded;
//XOR cipher with input, create encoded
xor_with_cipher(cipher, input, encoded);
//XOR cipher with encoded, create decoded (decoded = input)
xor_with_cipher(cipher, encoded, decoded);
//encoded string is in binary, it may contain zero and non-printable characters
//we can print the integer value of individual characters in encoded
cout << "encoded: ";
cout << hex << setfill('0');
for (unsigned int i = 0; i < encoded.length(); i++)
cout << setw(2) << (encoded[i] & 0xff);
cout << "\n";
cout << "decoded: " << decoded << "\n";
}
只是为了好玩,我一直在研究一个文本编码程序,它将对文本进行加扰。我让它几乎完美地工作,但似乎无法解决一个错误。基本上,文本大部分都会正确编码和解码,除了偶尔,程序会解码字符串中有一个字母错位。代码有点难看,我还没有尝试清理它,因为我还在解决这些错误,所以我很抱歉。它在各个部分的复制和粘贴也很糟糕,所以在我让它正常工作之后,优化的机会对我来说是巨大的。我有一种感觉,我知道错误在哪里,但是进行我认为需要进行的更正会导致无限循环。这是代码,底部有一些输出存储在注释中:
#include <iostream>
using namespace std;
void FillKey(char Key2[]);
void Encrypt();
void EncryptMessage(char Key3[], char Input2[], char MessageEncrypted2[]);
void Decrypt();
void DecryptMessage(char Key4[], char CodedInput2[], char NormalOutput2[]);
char ReturnDecodedCharacter(char Key5[], char Character);
const int STRING_SIZE=500;
const int ASCII_RANGE_SIZE_94=94;//Range from ASCII value 32 to 126 = 94
const int SHIFT_SET_32=32;//Move range up 32 values form (0-93) to (32 to 126)
int main()
{
int Choice;
do
{
cout << "Press 1 to encrypt" << endl;
cout << "Press 2 to decrypt" << endl;
cout << "Press other key to quit" << endl << endl;
cout << "Choice: ";
cin >> Choice;
if (Choice == 1)
Encrypt();
else if (Choice == 2)
Decrypt();
}
while (Choice==1 || Choice == 2);
}
void Encrypt()
{
int SecretNumber;
char Key[ASCII_RANGE_SIZE_94]={0};//One larger 0 - 93, not using 0
char Input[STRING_SIZE]={0};
char MessageEncrypted[STRING_SIZE]={0};
cout << "\nEnter Secret Number: ";
cin >> SecretNumber;
cin.ignore(1);//removes newline from input buffer
srand(SecretNumber);//Seed number for my random number generator
FillKey(Key);
cout << "\nInput message: ";
cin.getline(Input, STRING_SIZE);
EncryptMessage(Key, Input, MessageEncrypted);
cout << "\nEncrypted Message(copy inside of parenthesis): " << "(" << MessageEncrypted << ")" << endl << endl;
}
void FillKey(char Key3[])
{
int RandomNumber;
int KeySpot, j;
for (KeySpot=0; KeySpot<=ASCII_RANGE_SIZE_94; ++KeySpot)
{
RandomNumber = SHIFT_SET_32+rand()%ASCII_RANGE_SIZE_94;//0-93, then shifts up to 32-126 ASCII range
for (j=0; j<=KeySpot; ++j)//this bit of code checks to make sure new rand number isn't already used before
{
if (Key3[j] == RandomNumber)
{
RandomNumber = SHIFT_SET_32+rand()%ASCII_RANGE_SIZE_94;//0-93, then shifts up to 32-126
j=0;
}
}
Key3[KeySpot] = (char) RandomNumber;
}
}
void EncryptMessage(char Key3[], char Input2[], char MessageEncrypted2[])
{
for (int i=0; Input2[i]; ++i)
{
MessageEncrypted2[i]= Key3[((int) Input2[i])-SHIFT_SET_32];//-32 to get range back into 1-95 (range of Key)
}
}
void Decrypt()
{
int SecretNumber;
char Key[ASCII_RANGE_SIZE_94]={0};
char EncryptedMessage[STRING_SIZE]={0};
char DecodedMessage[STRING_SIZE]={0};
cout << "\nEnter Secret Number: ";
cin >> SecretNumber;
cin.ignore(1);//removes newline from input buffer
srand(SecretNumber);//Seed number for random number generator
FillKey(Key);
cout << "\nInput message to decode: ";
cin.getline(EncryptedMessage, STRING_SIZE);
DecryptMessage(Key, EncryptedMessage, DecodedMessage);
cout << "\nDecoded Message: " << DecodedMessage << endl << endl;
}
void DecryptMessage(char Key4[], char EncryptedMessage2[], char DecodedMessage2[])
{
for (int i=0; EncryptedMessage2[i]; ++i)
{
DecodedMessage2[i] = ReturnDecodedCharacter(Key4, EncryptedMessage2[i]);
}
}
char ReturnDecodedCharacter(char Key5[], char Character)
{
for (int Count=0; Count<=ASCII_RANGE_SIZE_94; ++Count)
{
if ((int) Character == Key5[Count])
{
return (char) Count+SHIFT_SET_32;//+32 to get back into 32-126 ASCII range
}
}
return 0;
}
/*
Press 1 to encrypt
Press 2 to decrypt
Press other key to quit
Choice: 2
Enter Secret Number: 1
Input message to decode: abcdefghijklmnopqrstuvqwyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
Decoded Message: Yj.63;nQb_ d"*!yTuc'8rTWi~1/|^ta5:?s+ODJwge42X,%q$SEvNZ9-h=kFL
Press 1 to encrypt
Press 2 to decrypt
Press other key to quit
Choice: 1
Enter Secret Number: 2
Input message: abcdefghijklmnopqrstuvqwyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
Encrypted Message(copy inside of parenthesis): (oZs?=LtFPSk<B +j]&xf!}]1"yq;zQm8\:>|T7_56VRH{9D-/*aOdbGCgAnJuv)
Press 1 to encrypt
Press 2 to decrypt
Press other key to quit
Choice: 2
Enter Secret Number: 2
Input message to decode: oZs?=LtFPSk<B +j]&xf!}]1"yq;zQm8\:>|T7_56VRH{9D-/*aOdbGCgAnJuv
Decoded Message: abcdefghijklmnopqrstuvqwyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
Press 1 to encrypt
Press 2 to decrypt
Press other key to quit
Choice: 1
Enter Secret Number: 3
Input message: abcdefghijklmnopqrstuvqwyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
Encrypted Message(copy inside of parenthesis): (w?oGY`hn5Ty% L\Z$qrDHR$"!F=WX}IV-Nf|g&+(Ps.pM*S)1t/e2@9v067{KC)
Press 1 to encrypt
Press 2 to decrypt
Press other key to quit
Choice: 2
Enter Secret Number: 3
Input message to decode: w?oGY`hn5Ty% L\Z$qrDHR$"!F=WX}IV-Nf|g&+(Ps.pM*S)1t/e2@9v067{KC
Decoded Message: abcdefghijklmnopqrstuvqwyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
Press 1 to encrypt
Press 2 to decrypt
Press other key to quit
Choice: 1
Enter Secret Number: 4
Input message: abcdefghijklmnopqrstuvqwyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
Encrypted Message(copy inside of parenthesis): (2RQ%?u*"_yNXs!=t;VWb9);]:+#>dqv$wU7(EiP[JgGI&pxmh4\ eafk}0^1ln)
Press 1 to encrypt
Press 2 to decrypt
Press other key to quit
Choice: 2
Enter Secret Number: 4
Input message to decode: 2RQ%?u*"_yNXs!=t;VWb9);]:+#>dqv$wU7(EiP[JgGI&pxmh4\ eafk}0^1ln
Decoded Message: bcdefghijklmnopqrstuvqwyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
Press 1 to encrypt
Press 2 to decrypt
Press other key to quit
Choice:
*/
如果您注意到,最后一个字符串(密码为 4)没有正确转换并丢失了初始 'a'。我认为错误出在 void FillKey
函数中 - 在 if 语句中 if (Key3[j] == RandomNumber)
我创建了一个新的随机数并设置 j=0
如果任何新生成的随机数与之前的随机数完全相同键中的那些(显然不能两次使用相同的字符)。所以我的想法是,j 被设置为 0,但在 for 循环之后,它递增并变为 1。所以程序不检查 Key3[3]
中的重复项,所以我将语句更改为 j=-1
,预测它并在 for 循环后将其归零,但随后程序卡住并且永远不会存在循环。
如有任何建议,我们将不胜感激。
这里有错误:
for (KeySpot=0; KeySpot<=ASCII_RANGE_SIZE_94; ++KeySpot)
应该是:
for (KeySpot=0; KeySpot < ASCII_RANGE_SIZE_94; ++KeySpot)
因为密钥大小是 ASCII_RANGE_SIZE_94
,其中包括零索引。同样的错误在ReturnDecodedCharacter
,应该是:
for (int Count=0; Count < ASCII_RANGE_SIZE_94; ++Count)
为了让代码更易读,可以这样写:
char ReturnDecodedCharacter(const char *key, int keysize, char Character)
{
for (int Count = 0; Count < keysize; ++Count)
{
if (Character == key[Count])
{
return (char)(Count + SHIFT_SET_32);//+32 to get back into 32-126 ASCII range
}
}
return 0;
}
然后在调用函数时将ASCII_RANGE_SIZE_94
作为keysize
传递
这也可以用 XOR 运算符来完成
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
void xor_with_cipher(const string &cipher, const string &src, string &dst)
{
for (unsigned int i = 0; i < src.length(); i++)
{
char c = src[i] ^ cipher[i];
dst.push_back(c);
}
}
int main()
{
string cipher;
//create a simple cipher key with rand()
//Note, rand **** should not **** be used in real cryptography applications
int secretKey = 123;
srand(secretKey);
for (int i = 0; i < 100; i++)
{
char c = rand() % 0xff;
cipher.push_back(c);
}
string input = "plain text";
string encoded;
string decoded;
//XOR cipher with input, create encoded
xor_with_cipher(cipher, input, encoded);
//XOR cipher with encoded, create decoded (decoded = input)
xor_with_cipher(cipher, encoded, decoded);
//encoded string is in binary, it may contain zero and non-printable characters
//we can print the integer value of individual characters in encoded
cout << "encoded: ";
cout << hex << setfill('0');
for (unsigned int i = 0; i < encoded.length(); i++)
cout << setw(2) << (encoded[i] & 0xff);
cout << "\n";
cout << "decoded: " << decoded << "\n";
}