Jump to content
  • Advertisement
Sign in to follow this  
RavynousHunter

Simple Encryption Gone Awry [solved]

This topic is 3606 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

It's been a long while since I posted here, but I have a bit of a problem on my hands, and I'm stumped as to how to solve it. It's in a program I have named the "Generic Encryption Program," a simple, command-line XOR-based encryption program that I've been working on for a while now in VC++ 2008 Express. My problem is is that it successfully encrypts the file, but when I check the file, it's size doesn't match the source file; the source file being 4kb in size, and the encrypted file being only 4 bytes in size. Also, when I exit, it gives me these errors: First-chance exception at 0x7c911e5a in GEP.exe: 0xC0000005: Access violation reading location 0x616d6d73. First-chance exception at 0x7c90eb74 in GEP.exe: 0xC0000008: An invalid handle was specified. First-chance exception at 0x7c9118c5 in GEP.exe: 0xC0000005: Access violation reading location 0x7079726b. Unhandled exception at 0x7c9118c5 in GEP.exe: 0xC0000005: Access violation reading location 0x7079726b. The code for the Encrypt() function is as follows:
void Encrypt(string file_loc, string destination, string dest_filename)
{
  string true_dest; // The real destination, with filename
  
  system("cls"); // Clear the console of old text.
  
  cout << "Generating true destination...\n";

  true_dest += destination + dest_filename + ".RH0";

  cout << "True destination generated...\n";
  
  ifstream in_file;
  ofstream out_file;
  
  cout << "Generating file streams...\n";

  in_file.open(file_loc.c_str(), ios::in | ios::binary);
  
  if (!in_file.is_open())
  {
    cout << "Error in opening input file, exiting...\n" << endl;
    
    system("PAUSE");
    system("EXIT");
  }
  out_file.open(true_dest.c_str(), ios::out | ios::binary | ios::app);
  
  if (!out_file.is_open())
  {
    cout << "Error in opening output (*.RH0) file, exiting...\n" << endl;
    
    system("PAUSE");
    system("EXIT");
  }
  
  cout << "File stream generation successful..." << endl;

  long long size;
  size = sizeof(in_file);
  char* file_mem = new char;
  
  in_file.read(file_mem, size);
  
  // Encryption begins here, XOR by 128.
  
  for (int i = 0; i < sizeof(file_mem); i++)
  {
    char xor_byte = file_mem ^ 128;
    out_file << xor_byte;
  }  
  
  // Encryption ends here.
  
  in_file.close();
  out_file.close();
  
  cout << "Encrypted file generated at location: " << true_dest.c_str();
  cout << endl << endl;

  system("PAUSE");
  system("EXIT");
}
The access violations always point me to the last "}" at the end of the function, so that's of no help... Anyone have any ideas as to what I may be doing wrong? [Edited by - RavynousHunter on December 5, 2008 6:45:47 AM]

Share this post


Link to post
Share on other sites
Advertisement
There are at least two problems in your code.

First is - you are incorrectly getting size of file. sizeof() operator will return size of variable, not what it contains. So sizeof(in_file) will return constant something like 144 (depending on your compiler). If you want to get size of file then seekg to end of file and use tellg to get current position in file.

Second problem is - you are allocating only 1 byte of memory (new char), but reading into memory a lot more bytes (size count). If you want to allocate more bytes then you should use new char [count_of_bytes] syntax. Or better - use std::vector<char> which will automaticaly manage memory for you.

Share this post


Link to post
Share on other sites
Thanks for the reply, however, I now get another error. VC++ tells me in the in_file.read(file_mem, size) line that I need to convert file_mem from a std::vector<char> to a char*, but I see no methods within the vector itself to do so.

I might be able to use a for loop to insert the file into memory byte by byte, but which method should I use to read each byte should I decide to use this approach?

Share this post


Link to post
Share on other sites
http://www.cplusplus.com/reference/iostream/istream/read.html

Read() excepts array. File_mem is not an array, but a pointer to one byte. If you want to read only one byte at once, you have to set size to 1 or use get().

Share this post


Link to post
Share on other sites
The problem is, is that I'm no longer using an array (and that method caused problems, as well), but am using a vector, which gives me this error:


gep.cpp(147) : error C2664: 'std::basic_istream<_Elem,_Traits>::read' : cannot convert parameter 1 from 'std::vector<_Ty>' to 'char *'
with
[
_Elem=char,
_Traits=std::char_traits<char>
]
and
[
_Ty=char
]
No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called


Could I use one of the cast functions (like static_cast, or dynamic_cast) to temporarily cast file_mem as a generic character array?

Share this post


Link to post
Share on other sites
You might be able to do &file_mem[0], which should get you a pointer to the start of the vectors memory, you'd have to make sure that the vector is already at a sufficient size to cover the data your going to read into it though, otherwise you'll overwrite memory that belongs to something else.

Share this post


Link to post
Share on other sites
Instead of in_file.read try

std::vector<char> file_mem((std::istreambuf_iterator<char>(in_file)),
(std::istreambuf_iterator<char>()));

Share this post


Link to post
Share on other sites
I would even go as far as suggesting...

void encrypt(const char* in_filename,
const char* out_filename)
{
std::ifstream in(in_filename, ios::in | ios::binary);
std::ofstream out(out_filename, ios::out | ios::binary | ios::app);
if (in && out)
std::transform(std::istream_iterator<char>(in),
std::istream_iterator<char>(),
std::ostream_iterator<char>(out),
xor);
}

char xor(char c)
{
return c ^ 128;
}

Share this post


Link to post
Share on other sites
If you want a potato (an array), you shouldn't try to use a pile of carrots (a vector) instead.

Read() has been designed for potatoes, so you should create a potato and pass it as a parameter instead of painting carrots brown and passing them.

int array_size = 10;
char buffer[array_size];
in_file.read(buffer, array_size);


It is as simple as that, where is problem?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!