I'm making a XOR based en/decryptor, that works like this. You have a plaintext character, for example 3, and a user key, for example 5. Written in bits:
3 = 00000011
5 = 00000101
Now if we do XOR operation, we get 6:
6 = 00000110
This can be reversed by saying 6 XOR 5, which is 3.
So I have made this program. But it's really buggy, it doesn't translate the text right, and i开发者_运维问答t adds a lot of characters in the end of the file, depending which key you are using.
using namespace std;
int main(int argc, char *argv[])
{
char buffer[5001];
ifstream fin("a.txt", ifstream::in);
ofstream fout("b.txt");
int key;
char znak;
// console
cout << "Key: ";
cin >> key;
fin.get(znak);
while(!fin.eof() && znak != ' ')
{
fin.get(buffer, sizeof(buffer));
}
for(int i = 0; i < sizeof(buffer); i++)
{
fout << function(key, buffer[i]);
}
cout << "done" << endl;
cin.get();
return 0;
}
char function(int key,char input)
{
return input ^ key;
}
Why doesn't the program translate the text right? And Why does it add characters to the end of the file?
From the looks of things, the encryption has almost nothing to do with anything (or at least with the problem) here.
while(!fin.eof() && znak != ' ')
A loop of the form while (!whatever.eof())
is pretty much guaranteed to work incorrectly.
fin.get(buffer, sizeof(buffer));
When you do this, note that it does not guarantee that it will read sizeof(buffer)
characters -- only that it won't read any more than that. You typically get fewer at the end of the file, when there simply aren't that many characters left to read. [Edit: I should also mention that you can read fewer in other places as well -- e.g., if you're reading from a network connection, it's fairly common to receive a partial buffer, but more later when it arrives.]
for(int i = 0; i < sizeof(buffer); i++)
So here, when you attempt to process sizeof(buffer)
characters, chances are pretty good that (especially on the last iteration) you're attempting to process more characters than you actually read. You can retrieve the number you read with gcount
, though I'm not sure I'd really recommend using it.
Personally, I'd probably do something like this:
class function {
char key;
public:
function(char k) : key(k) { }
char operator()(char input) { return key ^ input; }
};
int main() {
std::ifstream fin("a.txt");
std::ofstream fout("b.txt");
fin.noskipws();
std::transform(std::istream_iterator<char>(fin),
std::istream_iterator<char>(),
std::ostream_iterator<char>(fout),
function(key));
return 0;
}
Here are some items I noticed:
1. Operate in binary with unsigned char
data type.
A char
or signed char
may play havoc with your encryption scheme.
Open the files as binary
, so the OS doesn't translate the bytes:
Old:
char buffer[5001];
ifstream fin("a.txt", ifstream::in);
ofstream fout("b.txt");
Corrected:
const unsigned int BUFFER_SIZE = 4096; // Prefer multiples of 2.
ifstream fin("a.txt", ios::binary); // ifstream::in is redundant for an ifstream
ofstream fout("b.txt", ios::binary);
Be consistent with your data types.
The int
and char
types may be different sizes
Prefer unsigned char
if you want to play with bytes.
Reference: int key; char znak;
Use the I/O statement as an expression in the while
statement. In short, eof
is caused after reading:
while ((fin >> znak) && (znak != ' '))
i found some XOR encryption codes online which might help you
it is a beautifully written code in c https://code.google.com/p/xorencryption/
written in c++ http://programmingconsole.blogspot.in/2013/10/xor-encryption-for-alphabets.html
Look carefully at your code reading the file into the buffer. The get() function reads at most the number of characters you ask for; it'll be less at the end of the file. You should check how many were actually read with gcount() and only loop through those when doing your encryption step.
There seems to be a bit of other tidying-up you need, as well.
精彩评论