Search code examples
c++filegarbage

Weird characters appear at the end of file when encrypting it


I never thought I would have to turn to SO to solve this.

Alright so for more insight I am making my own encryption program. I'm not trying to make it good or anything it's just a personal project. What this program is doing is that it's flipping certain bits in every single byte of the character making it unreadable.

However every time I run the program and decrypt I get weird characters on the output. These characters seem to match the amount of lines as following:

enter image description here enter image description here ^^ text that I want to encrypt

enter image description here enter image description here ^^ after encrypting. (a lot of the text got cut off)

enter image description here enter image description here

^^ after decrypting. there's 10 null character corresponding to the amount of newlines. there also seems to be another weird '�' character. Where are these bytes coming from??

I've tried a lot of stuff. Here is my code if anyone needs it (it's compiled with default flags):

#include <iostream>
#include <fstream>
#include <cstring>
#include <string>

#define ENCRYPTFILE "Encrypted.oskar"

typedef unsigned char BYTE; 

char saltFunc(BYTE salt, char chr) {
   for(int i = 0; i < 8; i++) {
      if((salt >> i) & 1U) {
         chr ^= 1UL << i;
      }
   }

   return chr;
}

int main () {
   std::ofstream encryptFile(ENCRYPTFILE, std::ifstream::in);
   std::ifstream inputFile(ENCRYPTFILE, std::ifstream::in);
   unsigned int length;
   unsigned int lineLength;
   BYTE salt = 0b00000001;
   std::string line;

   std::cin.unsetf(std::ios::dec);
   std::cin.unsetf(std::ios::hex);
   std::cin.unsetf(std::ios::oct);

   //std::cout << "input salt in hex with a prefix 0x so for example. 0xA2" << std::endl;
   //std::cin >> std::hex >> salt;

   inputFile.seekg(0, inputFile.end);
   length = inputFile.tellg();
   inputFile.seekg(0, inputFile.beg);

   std::cout << lineLength << std::endl;

   char* fileBuffer = new char[length];
   char* encryptFileBuffer = new char[length];
   memset(fileBuffer, 0, length);
   memset(encryptFileBuffer, 0, length);

   while (inputFile.good()) { // just get file length in bytes.
      static int i = 0;
      fileBuffer[i] = inputFile.get();
      i++;
   }

   while (std::getline(inputFile, line))
      ++lineLength;

   inputFile.clear();
   encryptFile.clear();

   std::cout << "file size: " << length << std::endl;

   for(int i = 0; i < length; i++) {
      encryptFileBuffer[i] = saltFunc(salt, fileBuffer[i]);
      encryptFile << encryptFileBuffer[i];
   }

   inputFile.close();
   encryptFile.close();
   delete[] encryptFileBuffer;
   delete[] fileBuffer;
   return 0;
}

Solution

  • The problem is that you are measuring the length of the file in bytes, which, for text files, is not the same as the length in characters. But you are then reading it as characters, so you end up reading too many characters and then writing extra garbage after then end in the output file.

    Since you are getting one extra character per line, it is likely you are running on Windows, where line ending characters are two bytes in the file. That's where the extra incorrect length you are seeing is coming from.

    For encryption/decryption what you probably want to do is read and write the file in binary mode, so you are reading and writing bytes not characters. You do this by adding std::ios::binary into the flags when opening the file(s):

    std::ofstream encryptFile(ENCRYPTFILE, std::ifstream::in | std::ios::binary);
    std::ifstream inputFile(ENCRYPTFILE, std::ifstream::in | std::ios::binary);