-3

I have a key that's stored as a string and I'm trying to get the hex representation of the string. I don't want to convert from ASCII to HEX.

std::string keyInStr = "1314191A1B";

unsigned char keyInHex[5];

for (int i = 0; i < 5; i++)
 {
   keyInHex[i] =   keyInStr[i];
   printf("%02X ", keyInHex[i]);
 }

Current Output: 31 33 31 34 31

Expected Output:13 14 19 1A 1B

In another words, this is what I want to be stored in my array.

keyInHex[0] = 0x13;
keyInHex[1] = 0x14;
keyInHex[2] = 0x19;
keyInHex[3] = 0x1A;
keyInHex[4] = 0x1B;
Programmer
  • 15
  • 5

4 Answers4

0

The current output corresponds to the hex encoding of the ascii characaters in your string (0x31 for '1', 0x33 for '3', etc...). This is normal, since your code just copies the input one char per one char:

keyInHex[i] =   keyInStr[i];    // output in hex is the same as input in ascii

If you want to convert the input into hex, combining two input digits to make one output digit (e.g. '1' and '3' to produce one byte corresponding to 0x13, you need to iterate over your input string two by two, each time taking the binary equivalent to the hex digit expressed in ascii.

You do so by converting an ascii hex digit into a binary digit:

 if (keyInStr[i]>='A') 
     digit =  keyInStr[i]-'A'+0x0A;  // assuming that uppercase only is used 
 else digit = keyInStr[i]-'0';  

You can then combine two such digits with:

keyInHex[j] = (digit1<<4) | digit2;     

or if you didn't see bit operations yet in your course:

keyInHex[j] = digit1*16 + digit2;

As I don't want to do your homework, I let you as an exercise to rewrite the loop to process digits by 2. Attention: in the worst case, there might be an isolated digit in the last iteration.

keyInHex[i] = keyInStr[i]
Christophe
  • 68,716
  • 7
  • 72
  • 138
0

If you know that your string contains an exact hex string with an even amount of characters, this will work:

std::string keyInStr = "1314191A1B";
std::vector<char> keyInHex;

for (size_t i = 0; i < keyInStr.length(); i += 2)
{
    std::string currentByte = keyInStr.substr(i, 2);
    keyInHex.push_back(static_cast<char>(std::strtol(currentByte.c_str(), NULL, 16)));
}

for (size_t i = 0; i < keyInHex.size(); i++)
{
    std::cout << std::hex << std::setw(2) <<  (keyInHex.at(i) & 0xFF) << " ";
}
Govind Parmar
  • 20,656
  • 7
  • 53
  • 85
0

I came up with this:

#include <iostream>

using namespace std;

int main()
{
    std::string keyInStr = "1314191a1b";

    const int SIZE = 5;
    unsigned char keyInHex[SIZE];

    unsigned long long hexVal = stoull(keyInStr, nullptr, 16);

    for (int i = 0; i < SIZE; i++)
     {
       keyInHex[i] = (hexVal >> ((SIZE - i - 1) * 8)) & 0xFF;
       printf("%02X ", keyInHex[i]);
     }
    return 0;
}

You say you do not want to convert ASCII to hex, but I couldn't think of something that didn't involve a string to binary data conversion. From there it simply shifts the bits and does a mask.

Dillydill123
  • 693
  • 7
  • 22
0

The string shown is already in a hex representation. What you are really asking for is to DECODE that hex back to its original binary data, and then print that data as hex. Which is redundant. Just print the string as-is, inserting a space after every 2nd character, eg:

std::string keyInStr = "1314191A1B";

for (int i = 0; i < keyInStr.size(); i += 2)
{
   //printf("%.2s ", keyInStr.c_str()+i);
   std::cout << keyInStr.substr(i, 2) << " ";
}

Otherwise, if you intend to actually use the key binary data, then you do need to decode the string, eg:

unsigned char hex2dec(const std::string &s, size_t pos)
{
   char ch = s[pos];

   if (ch >= 'A' && ch <= 'F')
      return (ch - 'A') + 10;

   if (ch >= 'a' && ch <= 'f')
      return (ch - 'a') + 10;

   if (ch >= '0' && ch <= '9')
      return (ch - '0');

   // error!
}

unsigned char decodeHexByte(const std::string &s, size_t pos)
{
   return (hex2dec(s, pos) << 4) | hex2dec(s, pos+1);
}

std::string keyInStr = "1314191A1B";
unsigned char keyInHex[5] = {};

for (int i = 0, j = 0; i < 5; ++i, j += 2)
{
   keyInHex[i] = decodeHexByte(keyInStr, j);

   //printf("%02X ", keyInHex[i]);
   std::cout << std::hex << std::setw(2) << std::setfill('0') << (int) keyInHex[i] << " ";
}

Live Demo

Alternatively, if you are using C++11 or later:

std::string keyInStr = "1314191A1B";
unsigned char keyInHex[5] = {};

for (int i = 0; i < 5; ++i)
{
   keyInHex[i] = std::stoi(keyInStr.substr(i*2, 2), nullptr, 16);

   //printf("%02X ", keyInHex[i]);
   std::cout << std::hex << std::setw(2) << std::setfill('0') << (int) keyInHex[i] << " ";
}

Live Demo

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • This answers my question and I really like your alternative solution. Not sure why they gave me -3 given that I asked a valid question. – Programmer Feb 06 '19 at 21:20