I have a string declared like so.
CHAR bkp[40] = "dc74699a8381da395f10b"; <- this value comes from querying a registry value
In memory (using VS memory window) I see..
0x00000071432FF918 64 63 37 34 36 39 39 61 38 33 38 31 64 61 33 39 35 66 31 30 62 00 .. .. .. ..
I am trying to convert the string to memory so that when I examine that memory address I see..
0x00000071432FF918 dc 74 69 9a 83 81 da 39 5f 10 0b .. .. .. ..
My project is in C++ but the function requires that it gets returned to a char *
. So if the char array needs to be converted to a C++ string it can.
Simply iterate through the string, and for every 2-char pair, you can do some very simple calculations and bit shifts to extract the byte values. For example:
BYTE decodeHex(char c)
{
if (c >= '0' && c <= '9')
return c - '0';
else if (c >= 'A' && c <= 'F')
return (c - 'A') + 10;
else if (c >= 'a' && c <= 'f')
return (c - 'a') + 10;
else
// illegal! throw something...
}
CHAR bkp[] = "dc74699a8381da395f100b";
int slen = strlen(bkp);
BYTE *bytes = new BYTE[slen / 2];
int blen = 0;
for(int i = 0; i < slen; i += 2)
{
bytes[blen++] = (decodeHex(bkp[i]) << 4) | decodeHex(bkp[i+1]);
}
// use bytes up to blen as needed...
delete[] bytes;
The array is a character string, so you'll have to convert from characters to hex. Let's use the old fashioned method:
const unsigned int length = sizeof(bkp);
const std::string hex_digits = "0123456789abcdef";
std::vector<uint8_t> destination;
for (unsigned int index = 0U; index < length; index += 2U)
{
uint8_t byte_value = 0;
std::string::size_type position = hex_digits.find(bkp[index]);
if (position == std::string::npos)
{
std::cerr << "invalid hex value at position " << index << "\n";
break;
}
byte_value = position;
++index;
position = hex_digits.find(bkp[index]);
if (position == std::string::npos)
{
std::cerr << "invalid hex value at position " << index << "\n";
break;
}
byte_value = (byte_value * 256) + position;
destination.push_back(byte_value);
}
Note: the above code uses C++ features since the original post was tagged as C++.
You need to convert you character array to a binary. Your input array is a hex string so this is rather straigforward.
unsigned char toBinary(char c)
{
if (c >= '0' && c <= '9')
return c - '0';
return (c - 'a') + 10;
}
CHAR bkp[40] = "dc74699a8381da395f10b"
unsigned char b[20];
int bi = 0;
for(int i = 0; i < 40; i += 2)
{
char c = bkp[i];
unsigned char v = toBinary(bkp[i]) << 4;
v += toBinary(bkp[i+1])
b[bi++] = v;
}
Just for some fun, you can perform the conversion using non-conditional operations.
In general:
You can take the input, take the lower 4 bits to give us the 0->9, A->F or a->f and then take bit 6 and use it as a multiplier to add the +10 if needed.
#include <conio.h>
#include <stdio.h>
#include <string.h>
void HexStrToRaw(char* in, unsigned char* out)
{
for (int loop = 0, o_loop = 0; loop < strlen(in); loop += 2, o_loop++)
{
out[o_loop] = (((in[loop] & 15) + ((in[loop] >> 6) * 9)) << 4) | ((in[loop + 1] & 15) + ((in[loop + 1] >> 6) * 9));
}
}
int main(int argc, char** argv)
{
char in[40] = "dc74699a8381da395f10b";
unsigned char out[20];
HexStrToRaw(in, out);
for (int loop = 0; loop < sizeof(out); loop++)
{
printf("%d -> 0x%02x\n", loop, out[loop]);
}
return 0;
}
The output becomes:
0 -> 0xdc
1 -> 0x74
2 -> 0x69
3 -> 0x9a
4 -> 0x83
5 -> 0x81
6 -> 0xda
7 -> 0x39
8 -> 0x5f
9 -> 0x10
10 -> 0xb0
11 -> 0xcc
12 -> 0xcc
13 -> 0xcc
14 -> 0xcc
15 -> 0xcc
16 -> 0xcc
17 -> 0xcc
18 -> 0xcc
19 -> 0xcc
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.