1

So essentially with the libraries that i'm working with I cannot use std::string, as it uses a somewhat depreciated version of C++ I need to convert this xor function from using std::string to just using char or char *. I have been trying but I cannot figure out what I am doing wrong, as I get an error. Here is the code:

string encryptDecrypt(string toEncrypt) {
    char key[] = "DSIHKGDSHIGOK$%#%45434etG34th8349ty"; //Any chars will work
    string output = toEncrypt;

    for (int i = 0; i < toEncrypt.size(); i++)
        output[i] = toEncrypt[i] ^ key[i % (sizeof(key) / sizeof(char))];

    return output;
}

If anyone could help me out, that would be great. I am unsure as to why I cannot do it by simply changing the strings to char *.

Edit:

What I have tried is:

char * encryptDecrypt(char * toEncrypt) {
    char key[] = "DSIHKGDSHIGOK$%#%45434etG34th8349ty"; //Any chars will work 
    char * output = toEncrypt; 
    for (int i = 0; i < sizeof(toEncrypt); i++) 
        output[i] = toEncrypt[i] ^ key[i % (sizeof(key) / sizeof(char))]; 
    return output; 
}

Please note I am not trying to convert an std::string to char, I simply cannot use std::string in any instance of this function. Therefore, my question is not answered. Please read my question more carefully before marking it answered...

Absolute Zero
  • 25
  • 1
  • 7
  • what version of c++ are you using that doesn't have `std::string`? Can you post what you have tried? – NathanOliver Oct 06 '15 at 16:13
  • Nathan, I am using an sdk for a platform that has the string headers but does not allow you to use them. If you try to use them on execute the thread will not be created. Its weird. and here is the that I tried: `code`char * encryptDecrypt(char * toEncrypt) { char key[] = "DSIHKGDSHIGOK$%#%45434etG34th8349ty"; //Any chars will work char * output = toEncrypt; for (int i = 0; i < sizeof(toEncrypt); i++) output[i] = toEncrypt[i] ^ key[i % (sizeof(key) / sizeof(char))]; return output; }`code` Sorry about the formatting, I am unsure of how to place code in a comment. – Absolute Zero Oct 06 '15 at 16:16
  • Previously asked and answered in http://stackoverflow.com/a/7352131/227103 – YuppieNetworking Oct 06 '15 at 16:23
  • 2
    Possible duplicate of [std::string to char\*](http://stackoverflow.com/questions/7352099/stdstring-to-char) – YuppieNetworking Oct 06 '15 at 16:23
  • 2
    @YuppieNetworking no, not a duplicate. The question is how to write the same function using only C strings in place of `std::string`. – crashmstr Oct 06 '15 at 16:32

4 Answers4

2

The issue here is

char * output = toEncrypt; 

This is making output point to toEncrypt which is not what you want to do. What you need to do is allocate a new char* and then copy the contents of toEncrypt into output

char * encryptDecrypt(char * toEncrypt) {
    char key[] = "DSIHKGDSHIGOK$%#%45434etG34th8349ty"; //Any chars will work 
    int string_size = std::strlen(toEncrypt); 
    char * output = new char[string_size + 1]; // add one for the null byte
    std::strcpy(output, toEncrypt); //copy toEncrypt into output
    for (int i = 0; i < string_size; i++) 
        output[i] = toEncrypt[i] ^ key[i % (sizeof(key) / sizeof(char))]; 
    return output; 
}

Live Example

Since we are using dynamic memory allocation here we need to make sure that the caller deletes the memory when done otherwise it will be a memory leak.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • Thank you! This works, but the only thing is it does not encrypt the entire string for some weird reason. Only the first 3 or 4 characters. – Absolute Zero Oct 06 '15 at 16:29
  • `sizeof(toEncrypt)` should be `strlen` to get length of the string in characters. – crashmstr Oct 06 '15 at 16:30
  • If it's not working past the first few characters, it's likely that your input arguments contain the null byte. Therefore, `strlen` will NOT work for your purposes. Check my answer for a solution. – Jack O'Reilly Oct 06 '15 at 16:31
  • 1
    @AbsoluteZero Updated answer to fix that – NathanOliver Oct 06 '15 at 16:31
  • Ah, didn't notice that you hadn't updated the `sizeof`. That'd explain the partial encryption. I'd still recommend avoiding `strlen` if possible, depending on the requirements of possible input / output strings. – Jack O'Reilly Oct 06 '15 at 16:33
  • @JackO'Reilly True. I would pass the size of the string but I didn't want to change the prototype on the OP so `strlen` it is. – NathanOliver Oct 06 '15 at 16:35
  • It still has partial encryption. This along with Jack's answer fixed one part of it, but now it does not return the correct decrypted string. – Absolute Zero Oct 07 '15 at 02:42
  • @AbsoluteZero It is working in this live example: http://coliru.stacked-crooked.com/a/5f8c20469ae39865 – NathanOliver Oct 07 '15 at 11:56
2

sizeof() is a compile-time operator that evaluates the size of the type of its argument. When you do sizeof(toEncrypt), you're really just doing sizeof(char*) -- not the length of the string, which is what you want. You'll need to somehow indicate how long the toEncrypt string is. Here are two possible solutions:

  1. Add an integer argument to encryptDecrypt specifying the length of toEncrypt in characters.

  2. If you know that toEncrypt will never contain the null byte as a valid character for encryption / decryption (not sure of your application) and can assume that toEncrypt is null-terminated, you could use the strlen function to determine string length at runtime.

I'd recommend option 1, as strlen can introduce security holes if you're not careful, and also because it allows the use of null bytes within your string arguments.

Jack O'Reilly
  • 434
  • 2
  • 14
1

What error are you getting? You can easily use a char* to do the same thing, I've included a sample program that verifies the functionality. This was built under VS2012.

#include <string>
#include <stdio.h>

std::string encryptDecrypt( std::string toEncrypt)
{
    char key[] = "DSIHKGDSHIGOK$%#%45434etG34th8349ty"; //Any chars will work
    std::string output = toEncrypt;

    for (int i = 0; i < toEncrypt.size(); i++)
        output[i] = toEncrypt[i] ^ key[i % (sizeof(key) / sizeof(char))];

    return output;
}

void encryptDecrypt( char* toEncrypt )
{
    char key[] = "DSIHKGDSHIGOK$%#%45434etG34th8349ty"; //Any chars will work
    int len = strlen( toEncrypt );

    for (int i = 0; i < len; i++)
        toEncrypt[i] = toEncrypt[i] ^ key[i % (sizeof(key) / sizeof(char))];
}

int main( int argc, char* argv[] )
{
    const char* sample = "This is a sample string to process";
    int len = strlen( sample );
    char* p = new char[ len + 1 ];
    p[len] = '\0';
    strcpy( p, sample );

    std::string output = encryptDecrypt( sample );
    encryptDecrypt( p );

    bool match = strcmp(output.c_str(), p) == 0;
    printf( "The two encryption functions %smatch.\n", match ? "" : "do not "   );

    return 0;
}
Scott
  • 178
  • 1
  • 9
-1

Why not instead of string output = toEncrypt :

char *output = new char[std::strlen(toEncrypt) + 1];
std::strcpy(output, toEncrypt);
Cruiser
  • 1,618
  • 2
  • 16
  • 20