Hey, I have an problem with decrypting XOR encrypted string (every char is encrypted and appended to string). I have an "key", what original string was and the final "string" (arabic chars) but even with that info I have an problem (some chars doesnt match, "comma" every char and "-n" instead of "dot").
Can somebody take a look? First time doing something bitewise, maybe I misunderstood something.
Code should print "slash" (/) but printing -o
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
#include <iostream>
#include <windows.h>
#include <string>
std::string decrypt(std::string value){
std::string final;
int i = 0;
while (i < value.size()){
final.push_back((char)value.at(i) ^ 0x6F6);
++i;
}
return final;
}
int main()
{
std::cout << decrypt("ۙ") << std::endl;
return 0;
}
xor encryption produces binary (as in binary files: every possible byte is allowed).
I have not spent a lot of time trying to shovel the unprintables into std::string but you are going to get stuff like char 0-20 which in ascii are a mix of things that should not be printed.
I would try a vector of unsigned char instead of a string here.
and print that one char at a time in hex to see the encrypted data, or one letter at a time in ascii but be prepared for oddities when you do it.
then decrypt the vector, and you can dump that result back into a string (stuff a 0 char on the end of it like a c-string and vector can convert it from c-string to printable again).
If this is for any practical use, a constant key is very easily broken. Once you have it working, use <random> bytes and generate the random stream seed from the password/key/something.
wait... you sent empty string to decrypt? I missed that before.
the while loop does not execute in c++ for empty string.
.at is slow. if you can use [] instead, you should, and here, you know your index is safe and in range.
std::string crypt(std::string value) //xor self reverses, so encrypt and decrypt are same function
{
for(auto &c : value) //for every letter in value, alias that as 'c'
{
c ^= 0x6F6; //we modify c, which modifies value, but value is a copy of what was sent.
}
return value; //the copy. the original in main is unchanged.
}
int main()
{
string o{"abc"}; //non empty string
string s = crypt(o); //so we can check original
cout << "orig: " << o << endl; //unchanged by function verified
std::cout << s << std::endl; //unprintable nonsense, but it worked
s = crypt(s); //do we get abc back when we call it again?
std::cout << s << std::endl;
return 0;
}
sending "" (empty string) is still not going to do anything meaningful.
I ran it with some punctuation, numbers, etc and it still works and it prints junk for the junk characters...
a quick google tells me that
The representation for String and StringBuilder etc in Java is UTF-16
but you are using ascii (utf-8 I guess?) for this C++ code.
you can try wstring in c++...
(which needs wcout). L"string" is widened for a literal.
But I have not been able to get your 'expected' results.
If the goal is to duplicate java, it will take a bit of unraveling what java is doing vs what c++ is doing. I can assure you that a^b works the same in both, assuming both are unsigned (which java is wonky about). So if you can get it down to the same a & b for both languages, it WILL work, but that means understanding both languages well.
you are not doing anything 'wrong', you are just fighting a language translation issue.