0

I'm making a enciphering/deciphering program using XTEA algorithm. The encipher/decipher functions work fine, but when I encipher a file and then decipher it, I get some extra characters in the end of the file:

--- Original file ---
QwertY

--- Encrypted file ---
»¦æŸS@±­

--- Deciphered from encrypted ---
QwertY  ß*tÞÇ

I have no idea why the " ß*tÞÇ" appears in the end. I will post some of my code, but not all of it since it would be too long. The encipher/decipher function takes 64 bits data and 128 bits key, and encipher/decipher the data to the same block size, which is again 64 bits (similar functions here). It can then be written to a new file.

    long data[2]; // 64bits
    ZeroMemory(data, sizeof(long)*2);
    char password[16];
    ZeroMemory(password, sizeof(char)*16);

    long *key;
    if(argc > 1)
    {
        string originalpath = argv[1];
        string finalpath;
        string eextension = "XTEA";
        string extension = GetFileExtension(originalpath);
        bool encipherfile = 1;

        if(extension.compare(eextension) == 0) // If extensions are equal, dont encipher file
        {
            encipherfile = 0;
            finalpath = originalpath;
            finalpath.erase(finalpath.length()-5, finalpath.length());
        }

        ifstream in(originalpath, ios::binary);
        ofstream out(finalpath, ios::binary);

        cout << "Password:" << endl;
        cin.get(password,sizeof(password));
        key = reinterpret_cast<long *>(password);

        while(!in.eof())
        {
            ZeroMemory(data, sizeof(long)*2);
            in.read(reinterpret_cast<char*>(&data), sizeof(long)*2); // Read 64bits from file

            if(encipherfile == 1)
            {
                encipher(data, key);
                out.write(reinterpret_cast<char*>(&data), sizeof(data));
                continue;
            }
            if(encipherfile == 0)
            {
                decipher(data, key);
                out.write(reinterpret_cast<char*>(&data), sizeof(data));
            }
        }
Janman
  • 698
  • 1
  • 9
  • 25
  • possible duplicate of [Reading from text file until EOF repeats last line](http://stackoverflow.com/questions/21647/reading-from-text-file-until-eof-repeats-last-line) – Bo Persson Apr 09 '12 at 09:57
  • Thanks for the link, but I can assure you this is not a duplicate... You see in the link you gave me, they read 1 char at a time. I read a 64 bit block at a time, and even though the block only receives 1 byte before EOF, I should still be able to encipher/decipher it, and then the loop won't run again. – Janman Apr 09 '12 at 11:35
  • 2
    The block actually receives zero bytes before EOF. You still decipher and write one more time. The point is that `in.eof()` tells us if the previous read failed, not if the next read will be successful. – Bo Persson Apr 09 '12 at 12:36
  • This is a common problem. [Why is iostream::eof inside a loop condition considered wrong?](http://stackoverflow.com/a/5605159/445976) – Blastfurnace Apr 09 '12 at 13:10

1 Answers1

0

Check for eof immediately after your read, and if you get eof break out of the loop.

If you may have partial reads (i.e. it is possible to read fewer than all of the requested bytes), then you need also to call gcount to find out how many bytes you actually read, thus:

cin.read( ... )
if( cin.eof() )
    {
    streamsize bytesRead = cin.gcount();
    if( bytesRead > 0 )
       // process those bytes
    break;
    }
DRVic
  • 2,481
  • 1
  • 15
  • 22
  • Thanks for the answer, however, it doesn't help. When I read a block of file, I might only read half of the buffer (4 bytes), and then hit the eof, and if I break out of the loop then, the 4 bytes would just get discarded, and not get encrypted neither written to the new file. – Janman Apr 09 '12 at 15:33
  • Modified answer to account for possibility of incomplete buffer. – DRVic Apr 09 '12 at 16:16
  • Ah, thanks for the answer... There is just one more thing I have some problems with. Why does this happen only when I decipher? I mean, I use almost the same process for enciphering-deciphering. – Janman Apr 09 '12 at 17:42
  • Perhaps because you can readily see when its got longer than expected on decoding. I can't really say without knowing more about the enciphering/deciphering process. – DRVic Apr 09 '12 at 20:44