Thread: One of those nasty file read/write issues

  1. #1
    Kiss the monkey. CodeMonkey's Avatar
    Join Date
    Sep 2001
    Posts
    937

    One of those nasty file read/write issues

    So, I've been working on this object-oriented xor file encryptor of mine (Yeah, I know, what's the point), and I've come to an almost-done roadblock. It seems that for text and bitmap files my algorith functions correctly. However, ecrypting and then decrypting a wav file yields a "wrong format" erro when I try to play it in winamp. Obviously, I messed up some bits. Unfortunately, I don't know which bits or why. I've included excerpts from functions that encode and decode files. Yes, I'm using ios::binary.

    Encoding:
    Code:
    //The actual encoding (writing)
     
     unsigned long int counter = 0;
     writer.open(encoded_path.c_str(),ios::binary);
     if(!writer) return CRYPT_FAIL;
     
     writer.write("XOR_CODEC_ENCRYPTED_FILE@",25); //write branding
     writer.write(orig_name.c_str(),orig_name.size());//write original file name
     writer.put('@');//separation character
     for(int y = 0; y < password.size(); y++) writer.put( (password[y] ^ PASSWORD_KEY) );
     writer.put('@'); //separation character
     writer.write(key.c_str(),key.size()); //write key
     writer.put('@'); //separation character
     
     char in_byte = '\0';
     cout << "Encrypting..." << endl;
     while( !((reader.get(in_byte)).eof()) )     // while get() does not set eof bit (get() into in_byte)
     {
      //ok, so this reads through input (with get) and writes char by char (using put)
      //    the xor-ed data. Modulus is used so counter can increase
      //    to whatever, while for key[index], index { [0,255]
      //    Thus, the key is effectively cycled through continuously
      writer.put( static_cast<char>(in_byte ^ key[counter % KEY_SIZE]) );
      counter++;
     }
     cout << "Encryption complete." << endl;
     reader.clear();//eof
     reader.seekg(0,ios::beg);//rewind
     //Note: as currently written, the encoder has a 4,294,967,295 byte limit ( max_val(unsigned long int) )
     encoded = true;
    Now, when the decoder is called, the seek pointer on the encoded file is already past my little header, so (theoretically) only the original contents of the file are written):
    Code:
     unsigned long int counter = 0;
     char in_byte = '\0';
     cout << "Decrypting..." << endl;
     while( !((reader.get(in_byte)).eof()) )     // while get() does not set eof bit (get() into in_byte)
     {
      //ok, so this reads through input (with get) and writes char by char (using put)
      //    the un-xor-ed data. Modulus is used so counter can increase
      //    to whatever, while for key[index], index { [0,255]
      //    Thus, the key is effectively cycled through continuously
      writer.put( static_cast<char>(in_byte ^ key[counter % KEY_SIZE]) );
      counter++;
     }
     cout << "Decryption complete." << endl;
     reader.clear();//eof
     reader.seekg(0,ios::beg);//rewind
    PS: I apologize in advance for using eof() a loop conditional, but I don't think that's the problem (correct me if I'm wrong).
    "If you tell the truth, you don't have to remember anything"
    -Mark Twain

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    1. Are the input and output files the same size?

    2. Prepare a 256 byte file with each byte set to 00, 01, 02 ... FF
    - then encrypt it and decrypt it back to another file.
    - then compare one set of 256 bytes with another set of 256 bytes.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    have you tried the fc to understand which and how many bytes are broken?
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  4. #4
    Kiss the monkey. CodeMonkey's Avatar
    Join Date
    Sep 2001
    Posts
    937
    I will certainly try Salem's idea. What do you mean, vart? fc?
    "If you tell the truth, you don't have to remember anything"
    -Mark Twain

  5. #5
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    >for(int y = 0; y < password.size(); y++) writer.put( (password[y] ^ PASSWORD_KEY) );
    Did you try decrypting the password, and see what it prints?

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    fc is the command line compare tool

    fc /b oldfile newfile
    Will tell you the positions where corresponding bytes in two files differ.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. sequential file program
    By needhelpbad in forum C Programming
    Replies: 80
    Last Post: 06-08-2008, 01:04 PM
  2. To find the memory leaks without using any tools
    By asadullah in forum C Programming
    Replies: 2
    Last Post: 05-12-2008, 07:54 AM
  3. Can we have vector of vector?
    By ketu1 in forum C++ Programming
    Replies: 24
    Last Post: 01-03-2008, 05:02 AM
  4. Possible circular definition with singleton objects
    By techrolla in forum C++ Programming
    Replies: 3
    Last Post: 12-26-2004, 10:46 AM
  5. Making a LIB file from a DEF file for a DLL
    By JMPACS in forum C++ Programming
    Replies: 0
    Last Post: 08-02-2003, 08:19 PM