Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

XOR char returns wrong values

26 views
Skip to first unread message

daved170

unread,
Dec 21, 2009, 9:56:01 AM12/21/09
to
Hello everyone,
I got assignment - I got a binary file that was built by scrambling
string with XOR 0xFF

That file is my input file for my program. I'm suppose to write a
simple C++ program that read that file and scramble the text with 0xFF
so I could reveall the origin string.

Unfortunatly when I open my output file I got some rubbish charecters
in addition to the wanted string. I think this rubbish charecters
where instead of space or end line.

Here's my code:

string str;
char c;
ifstream in_File(argv[1]); // Binary File
ofstream in_File(argv[2]); // Text File

while(1)
{
in_File >> c;
if(!in_File.eof())
{
char sc = (char)(c^0xFF);
str.append(1,sc);
}
else
break;
}

out_File << str;
out_File.flush();
out_File.close();
in_File.close();


any idea?

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Francis Glassborow

unread,
Dec 21, 2009, 7:18:34 PM12/21/09
to

Yes. You need to know if just letters were encoded or if punctuation and
numbers were as well. You also need to consider the end of line coding.
IOWs you need to know exactly how the original coding was done and then
write a program that decodes only those parts that were encoded.

I note that you are reading the input file as a binary file. That is
fine but if it was originally created as a text file you may have to
worry about such things as newline characters (and how they were encoded
because those are system dependent.)

Ulrich Eckhardt

unread,
Dec 21, 2009, 7:22:41 PM12/21/09
to
daved170 wrote:
> I got assignment - I got a binary file that was built by scrambling
> string with XOR 0xFF
>
> That file is my input file for my program. I'm suppose to write a
> simple C++ program that read that file and scramble the text with 0xFF
> so I could reveall the origin string.
>
> Unfortunatly when I open my output file I got some rubbish charecters
> in addition to the wanted string. I think this rubbish charecters
> where instead of space or end line.
>
> Here's my code:
>
> string str;
> char c;
> ifstream in_File(argv[1]); // Binary File
> ofstream in_File(argv[2]); // Text File
>
> while(1)
> {
> in_File >> c;
> if(!in_File.eof())

This is wrong. Use this idiomatic version:

while(in >> c)

However, this still presents a problem, namely that it will skip whitespace
(spaces, tabs, newlines). Instead, you could use

while(in.get(c))

which will also include whitespace.

> char sc = (char)(c^0xFF);
> str.append(1,sc);
> }
> else
> break;
> }
>
> out_File << str;
> out_File.flush();
> out_File.close();
> in_File.close();

Some further notes:
* You read one file byte by byte, store it in a growing string and then
write that string into the output file. What I would suggest instead is to
read one byte, transform it and then write it again, i.e. without
intermediate storage.
* Flushing and closing the output is unnecessary. If you want, you can
flush it and then test the streamstate to make sure it was successfully
written, but closing is automatically done in the destructor of
std::ofstream.
* Closing the input stream is unnecessary, too. If you want to play safe,
check that the streamstate is 'fail' and 'eof' at the end, without the 'eof'
actual reading failed for some other reason.
* Handling chars as bytes is inconvenient, I would rather use unsigned
char. I'm not sure if std::istream has a get() overload taking an unsigned
char though. The slightly weird behaviour concerning higher bits is also
what could cause some confusion, I'm not 100% sure what problem exactly you
saw.

Uli

Jonathan Lee

unread,
Dec 21, 2009, 7:28:53 PM12/21/09
to
On Dec 21, 9:56 am, daved170 <daved...@gmail.com> wrote:
> Unfortunatly when I open my output file I got some rubbish charecters
> in addition to the wanted string. I think this rubbish charecters
> where instead of space or end line.

When I ran your code I got an output file significantly
shorter than the original. The cause is the use of
operator>> which is a *formatted* getter. I didn't do
a byte-for-byte comparison, but it's probably skipping
end-of-lines and such. Using the unformatted get
function of ifstream fixed the problem.

Also, you should probably look at this wrt your end-of-file
test:

http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.5

If you combine the two changes, you can cut that
while loop down significantly.

--Jonathan

Nick Hounsome

unread,
Dec 21, 2009, 7:27:32 PM12/21/09
to

Just commenting it "// Binary file" doesn't make it so.
You need to open with mode ios::binary

The "proper" way to do what you are trying to do is to provide a
custom streambuf - If you do it that way then it doesn't matter
whether you open as text or binary (provided that it is the same for
read and write) because the conversion is done at a lower level.

(You might also want to consider rot13 instead of xor FF just because
there are utilities that use it already)

Thomas Maeder

unread,
Dec 21, 2009, 7:24:16 PM12/21/09
to
daved170 <dave...@gmail.com> writes:

> I got assignment - I got a binary file that was built by scrambling
> string with XOR 0xFF
>
> That file is my input file for my program. I'm suppose to write a
> simple C++ program that read that file and scramble the text with 0xFF
> so I could reveall the origin string.
>
> Unfortunatly when I open my output file I got some rubbish charecters
> in addition to the wanted string. I think this rubbish charecters
> where instead of space or end line.
>
> Here's my code:
>
> string str;
> char c;
> ifstream in_File(argv[1]); // Binary File
> ofstream in_File(argv[2]); // Text File

[This is obviously not the code you tried. Please post real code;
those who might be willing to respond to you normally don't like to
make guesses about the real code.]


> while(1)
> {
> in_File >> c;
> if(!in_File.eof())

1. The operation

in_File >> c

has a return value which, like other return values, shouldn't be
ignored by the caller.

Among other things, this return value informs the caller about the
success of the input operation. If operator>> is used to iterate over
a stream, its return value is normally a better choice for controlling
the length of the iteration than the return value of eof(). E.g.:

while (inFile >> c)
{
...
}


But:

2. operator>> is dealing with *formatted* ("textual") input, while
your input is unformatted ("binary"). The Standard Library input
streams have different operations for dealing with unformatted input,
which you should use. One difference between formatted and unformatted
input is that the former ignores whitespace characters.

Maxim Yegorushkin

unread,
Dec 22, 2009, 12:17:25 AM12/22/09
to

You probably need to open the files in binary mode and instead of using
formatted stream operators << and >> use get() and put():

#include <fstream>

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

ifstream in_File(argv[1], ios_base::binary);
ofstream out_File(argv[2], ios_base::binary);

while(1)
{
int byte = in_File.get();
if(in_File.eof())
break;
byte ^= 0xff;
out_File.put(byte);
}
}

--
Max

0 new messages