0

I am trying to test something and I need to assume that the input is from a client using TCP and that the data is a buffer or maybe a byte array.

So this is my try:

unsigned char buf[] = { 99, 249, 117, 130, 110, 227, 171, 204, 30, 201, 225, 130, 203, 206, 74, 88, 94, 12, 223, 172, 60, 12, 173, 26, 145, 163, 112, 124, 99, 239, 188, 98, 103, 85, 163, 135, 125, 140, 186, 220, 207, 35, 185, 14, 22, 58, 36, 239, 124, 107, 29, 27, 44, 246, 165 };

So assuming that is from the client. I would like to test to process it:

xor256.Decrypt(buf, result, sizeof(buf));

But Decrypt is:

void XOR256::Decrypt(char const* in, char* result, size_t n)

So how do I fix this?

Problems:

  • Cannot initialise a variable of type const char * with an lvalue of type unsigned char[55]

  • I am confused with this. I want to get the result but this function does not return anything. But it points data to result. So how do I get the data?

  • I'm new to C++


int main(int argc, const char * argv[])
{
    CXOR256Stream xor256;

    char *nkey = new char[256];

    int a = 111;
    int b = 222;

    memset(nkey, 0x00, 256);
    sprintf((char*)nkey, "%.5d_XXX%.5d_XXX_%.5d", (a+10), (b+10), (a+b));


    unsigned char s[] = { 99, 249, 117, 130, 110, 227, 171, 204, 30, 201, 225, 130, 203, 206, 74, 88, 94, 12, 223, 172, 60, 12, 173, 26, 145, 163, 112, 124, 99, 239, 188, 98, 103, 85, 163, 135, 125, 140, 186, 220, 207, 35, 185, 14, 22, 58, 36, 239, 124, 107, 29, 27, 44, 246, 165 };

    const char* buf = s; // error here
    char result[50];

    xor256.Initialize(nkey, 256, 2);
    xor256.Decrypt(buf, result, sizeof(buf));

    // no error here but I'm confused on getting the data from decrypt so is this right?
    cout << result << endl;

    return 0;
}
majidarif
  • 18,694
  • 16
  • 88
  • 133
  • Can you show your entire test function? – Addison Jun 22 '14 at 06:36
  • Which line are you getting the error? – Addison Jun 22 '14 at 06:40
  • @Addison see updated source on question. thank you. – majidarif Jun 22 '14 at 06:40
  • 1
    Try making your `s[]` array just a char array, instead of unsigned. – Addison Jun 22 '14 at 06:41
  • @Addison yes, but that would error to: `constant expression evaluates to 249 which cannot be narrowed to type char` – majidarif Jun 22 '14 at 06:42
  • @Addison that isn't going to fly. `char` has no standard-defined representation for values above 127 assuming regular octets. – WhozCraig Jun 22 '14 at 06:43
  • I see. Then I don't think I know enough C++ to answer this. – Addison Jun 22 '14 at 06:46
  • Strangely, I don't get these errors in C, just warnings. It's nothing to worry about if this is for network I/O. Bytes are bytes no matter how you are interpreting them. `char` and `unsigned char` are the same size. If you convert 249 to `char`, it'll overrun to a negative number, but if you convert that to `char`, you'll get the original value. – sudo Jun 22 '14 at 07:03
  • @9000 could be but I can't compile it as I get the error `constant expression...cannot be narrowed to type char` – majidarif Jun 22 '14 at 07:08

2 Answers2

3

To be honest, this is a you-need-to-learn-the-langauge better problem. I don't intend that to sound harsh, so please don't take it as such. Learning by example is certainly understandable, and many, including myself, learn well as-such. I can produce one (example), but you can't take this as a "well, that problem is solved", because the real problem is learning the language (and trust me, the language is awesome, so its worth the pain).

Anyway, on to your code. Assuming you don't want the ensuing memory leak (the dynamic allocation is not needed), the simplest answer is this:

int main(int argc, const char * argv[])
{
    CXOR256Stream xor256;

    char nkey[256] = {0};

    int a = 111;
    int b = 222;
    sprintf(nkey, "%.5d_XXX%.5d_XXX_%.5d", (a+10), (b+10), (a+b));

    unsigned char s[] = 
    { 
      99, 249, 117, 130, 110, 227, 171, 204, 30, 201, 225, 
      130, 203, 206, 74, 88, 94, 12, 223, 172, 60, 12, 173, 
      26, 145, 163, 112, 124, 99, 239, 188, 98, 103, 85, 163, 
      135, 125, 140, 186, 220, 207, 35, 185, 14, 22, 58, 36, 
      239, 124, 107, 29, 27, 44, 246, 165 
    };


    char result[sizeof(s)] = {0};

    xor256.Initialize(nkey, sizeof(nkey), 2);
    xor256.Decrypt(reinterpret_cast<char const*>(s), result, sizeof(s));
    cout << result << endl;

    return 0;
}

Of note:

  • The dynamic buffer is not needed.
  • sizeof(buf) is flat-wrong for the size parameter of your decrypt. That is the size of a pointer, you need the number of bytes in the cipher-text.
  • The crux of your question, the API expects the address to constant char data, your passing an address to unsigned char data. in this situation a reinterpret_cast<> is feasible. That isn't something you lightly throw around in C++, so don't get used to it.

That said, if I understand the code you're trying to call, your buffer sizes may need work. the XOR256Stream algorithm package I think you're using should document the precise buffer sizes needed. I suspect that result buffer of length 50 won't be sufficient, but that isn't the root of your question. This should at least get you started. Best of luck.

WhozCraig
  • 65,258
  • 11
  • 75
  • 141
  • Better and more complete answer than mine, but I should point out: `char result[sizeof(s)]` should be `char result[sizeof(s)/sizeof(char)]`. – sudo Jun 22 '14 at 07:12
  • @WhozCraig, Thank you but I honestly think `C++` is really hard to learn. I don't know where to start. Though I am very familiar with interpreted languages like php, python, ruby or javascript. – majidarif Jun 22 '14 at 07:13
  • @9000 `sizeof(char)` is defined by the language standard to *always* be **one**, even if `char` is multiple octets. I know, it sounds odd, but its true. The division is not needed. – WhozCraig Jun 22 '14 at 07:14
  • @WhozCraig you seem to be very familiar with c, is there anywhere that is good to start? – majidarif Jun 22 '14 at 07:18
  • @WhozCraig Yes, you're right. I've been told otherwise, but it is indeed always 1. – sudo Jun 22 '14 at 07:19
  • 1
    @majidarif Start with some of the more popular beginners texts [**here**](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). I strongly suggest you write a **ton** of short example code as you learn to strengthen good habits. Spend an hour a day or so just reading on [cppreference.com](http://www.cppreference.com). Learn the standard library as well as the language. it will pay off with *enormous* benefits in the long run. – WhozCraig Jun 22 '14 at 07:21
  • @9000 no worries. If you really wanted to get an octet-count buffer (for whatever twisted reasons you have) you can do so by *multiplying* against `(CHAR_BIT/8)` but i've honestly never had a reason to do so. Its not uncommon to see it done as you showed, and any remotely decent compiler will toss out the division entirely, so no harm except extra keystrokes. =P – WhozCraig Jun 22 '14 at 07:25
  • 1
    @WhozCraig Yeah, I still like to do it anyway just to keep it consistent with the parts where I'm doing something like `sizeof(foo)/sizeof(int)`. I thought until now it was also required :) – sudo Jun 22 '14 at 07:27
  • 1
    @9000 **that** is likely the best reason I've heard doing it regardless of its otherwise-meaningless effects. Well presented too. If you're getting into that habit with arrays, I usually use `sizeof(arr)/sizeof(*arr)`, which takes the type out of the question and puts it back on the decl, but the practice still stands. GJ. – WhozCraig Jun 22 '14 at 07:30
2

You just need a typecast.

const char* buf = (const char*) s;

You'll get negative numbers for those above 127. Converting between char and unsigned char does not cause any loss, so it's fine as long as you handle it properly elsewhere. Edit: However, you have to be careful with this because conversion can be unpredictable unless you are going to char then straight back.

sudo
  • 5,604
  • 5
  • 40
  • 78