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;
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;
}
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++.
Just for some fun, you can perform the conversion using non-conditional operations.
In general:
'A' = 64, 'a' = 96, both of which have bit 6 set (value 64 decimal)
'0' = 48, so does not have the 6th bit set.
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
Related
I want to fill a 8 x 8 matrix with values in a special order (see example below), but I don´t know how to do that. Each numer stands for the ordering number: For example: #3 in the matrix is the third value of a e.g. a measurment I want to add.
The Order should be:
1 2 5 6 17 18 21 22
3 4 7 8 19 20 23 24
9 10 13 14 25 26 29 30
11 12 15 16 27 28 31 32
33 34 37 38 49 50 53 54
35 36 39 40 51 52 55 56
41 42 45 46 57 58 61 62
43 44 47 48 59 60 63 64
Does anybody knows an algorithmus to do that?
I have tried this, but that´s not a good way to to it, and it´s not working for the whole matrix
int b= 0, ii = 0, a = 0, iii = 0
i are different measurement values
and now a for loop
if (ii == 1)
{
b++;
}
if (ii == 2)
{
a++, b--;
}
if (ii == 3)
{
b ++;
}
tempMatrix[a][b] = i;
cout << "TempMatrix " << tempMatrix[a][b] << " a " << a << " b " << b << endl;
if (ii == 3)
{
ii = -1;
a --;
b ++;
}
if (iii == 7)
{
a = a + 2;
b = 0;
iii = -1;
}
Use recursion:
#include <iostream>
using namespace std;
void f(int a[8][8], int current, int x, int y, int size) {
if (size == 1) {
a[x][y] = current;
return;
} else {
size /= 2;
int add_for_each_square = size * size;
f(a, current, x, y, size);
f(a, current + add_for_each_square, x, y + size, size);
f(a, current + 2 * add_for_each_square, x + size, y, size);
f(a, current + 3 * add_for_each_square, x + size, y + size, size);
}
}
int main() {
int a[8][8];
f(a, 1, 0, 0, 8);
for (int i = 0; i < 8; ++i) {
for (int j = 0; j < 8; ++j) {
cout << a[i][j] << " ";
}
cout << endl;
}
}
If the matrix will always be a fixed size, then you can generate two lookup tables for row and column indexes into the matrix. Then, just pass your index through these tables to get the desired positions in the matrix.
const auto MATRIX_SIZE = 8;
const std::array<int, MATRIX_SIZE*MATRIX_SIZE> row_lookup = {{...}}; //put pre-computed values here.
const std::array<int, MATRIX_SIZE*MATRIX_SIZE> col_lookup = {{...}};
for(size_t i = 0; i < MATRIX_SIZE * MATRIX_SIZE; i++)
{
auto val = get_coefficient(i);
auto row = row_lookup[i];
auto col = col_lookup[i];
mat[col][row] = val;
}
This question already has answers here:
Convert two ASCII Hexadecimal Characters (Two ASCII bytes) in one byte
(6 answers)
Closed 6 years ago.
I have a typical use case where i need to convert the unsigned char values to hexadecimal.
For example,
unsigned char *pBuffer = (unsigned char *)pvaluefromClient //where pvaluefromclient is received from a client
The length of pBuffer is 32 bytes and it holds the value as follows,
(gdb) p pBuffer
$5 = (unsigned char *) 0x7fd4b82cead0 "EBA5F7304554DCC3702E06182AB1D487"
(gdb) n
STEP 1: I need to split this pBuffer value as follows,
{EB,A5,F7,30,45,54,DC,C3,70,2E,06,18,2A,B1,D4,87 }
STEP 2: I need to convert the above splited values to decimal as follows,
const unsigned char pConvertedBuffer[16] = {
235,165,247,48,69,84,220,195,112,46,6,24,42,177,212,135
};
Any idea on how to achieve the STEP1 and STEP2? any help on this would be highly appreciated
How about something like this:
unsigned char *pBuffer = (unsigned char *)pvaluefromClient //where valuefromclient is received from a client
int i, j;
unsigned char target[16]
for(i=0;i<32;i+=2)
{
sscanf((char*)&pBuffer[i], "%02X", &j);
target[i/2] = j;
}
You can create a function that takes two unsigned chars as parameter and returns another unsigned char. The two parameters are the chars (E and B for the first byte). The returned value would be the numerical value of the byte.
The logic would be :
unsigned char hex2byte(unsigned char uchar1, unsigned char uchar2) {
unsigned char returnValue = 0;
if((uchar1 >= '0') && (uchar1 <= '9')) {
returnValue = uchar1 - 0x30; //0x30 = '0'
}
else if((uchar1 >= 'a') && (uchar1 <= 'f')) {
returnValue = uchar1 - 0x61 + 0x0A; //0x61 = 'a'
}
else if((uchar1 >= 'A') && (uchar1 <= 'F')) {
returnValue = uchar1 - 0x41 + 0x0A; //0x41 = 'A'
}
if((uchar2 >= '0') && (uchar2 <= '9')) {
returnValue = (returnValue <<8) + (uchar2 - 0x30); //0x30 = '0'
}
else if((uchar2 >= 'a') && (uchar2 <= 'f')) {
returnValue = (returnValue <<8) + (uchar2 - 0x61 + 0x0A); //0x61 = 'a'
}
else if((uchar2 >= 'A') && (uchar1 <= 'F')) {
returnValue = (returnValue <<8) + (uchar2 - 0x41 + 0x0A); //0x41 = 'A'
}
return returnValue;
}
The basic idea is to calculate the numerical value of the chars and to reassemble a number from two chars (hence the bit shift)
I'm pretty sure there are multiple more elegant solutions than mine here and there.
void Conversion(char *pBuffer, int *ConvertedBuffer)
{
int j = 0;
for(int i = 0; i < 32; i += 2)
{
std::stringstream ss;
char sz[4] = {0};
sz[0] = pBuffer[i];
sz[1] = pBuffer[i+1];
sz[2] = 0;
ss << std::hex << sz;
ss >> ConvertedBuffer[j];
++j;
}
}
int main()
{
char Buffer[] = "EBA5F7304554DCC3702E06182AB1D487";
int ConvertedBuffer[16];
Conversion(Buffer, ConvertedBuffer);
for(int i = 0; i < 16; ++i)
{
cout << ConvertedBuffer[i] << " ";
}
return 0;
}
//output:
235 165 247 48 69 84 220 195 112 46 6 24 42 177 212 135
I am trying to develop a Ascii85 decoder in c++, in order to parse a bitmap file from an adobe illustrator file (*ai).
I have found an algorithm in java here and I have tried to rewrite it in c++.
The problem is that I have some cases that my encoded text is not being decoded correctly. For example if character "a" is the 7th and final character in my string (before the encoding) it is decoded as "`", which is the previous character in the ascii table. It is weird because I have tried to make the calculations of the algorithm manually, and I get "`" as a result. I am wondering if there is a bug in the algorithm or if it is not the correct algorithm for adobe ascii85 decoding.
Here is my code:
#include <QCoreApplication>
#include <stdio.h>
#include <string.h>
#include <QDebug>
// returns 1 when there are no more bytes to decode
// 0 otherwise
int decodeBlock(char *input, unsigned char *output, unsigned int inputSize) {
qDebug() << input << output << inputSize;
if (inputSize > 0) {
unsigned int bytesToDecode = (inputSize < 5)? inputSize : 5;
unsigned int x[5] = { 0 };
unsigned int i;
for (i = 0; i < bytesToDecode; i++) {
x[i] = input[i] - 33;
qDebug() << x[i] << ", i: " << i;
}
if (i > 0)
i--;
unsigned int value =
x[0] * 85 * 85 * 85 * 85 +
x[1] * 85 * 85 * 85 +
x[2] * 85 * 85 +
x[3] * 85 +
x[4];
for (unsigned int j = 0; j < i; j++) {
int shift = 8 * (3 - j); // 8 * 3, 8 * 2, 8 * 1, 8 * 0
unsigned char byte = (unsigned char)((value >> shift) & 0xff);
printf("byte: %c, %d\n", byte, byte);
*output = byte;
output++;
}
}
return inputSize <= 5;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
char x__input[] = "<~FE1f+#;K?~>";
unsigned char x__output[128] = { 0 };
char *input = x__input + 2;
unsigned int inputSize = (unsigned int)strlen(input);
inputSize -= 2;
unsigned char *output = x__output;
printf("decoding %s\n", input);
for (unsigned int i = 0; i < inputSize; i += 5, input += 5, output += 4)
if(decodeBlock(input, output, inputSize - i))
break;
printf("Output is: %s\n", x__output);
return a.exec();
}
What happens when inputSize is not multiple of 5??
unsigned int bytesToDecode = (inputSize < 5)? inputSize : 5;
you ASSUME that bytesToDecode is 5, while there will be some bytes with unknown values
So, when your character is the last at position 7, the above condition is true.
If the input is not a multiple of 5, then it MUST be padded with the value "u".
For more details about the encoding / decoding process, please check the Wikipedia page, where it is pretty well explained:
http://en.wikipedia.org/wiki/Ascii85#Example_for_Ascii85
I have Hexadecimal format IP4 address which needs to be converted to string. Could you please let me know what needs to be changed in the below code to get the right answer. Thanks a lot for the support.
int main (void) {
char buff[16];
string IpAddressOct = "EFBFC845";
string xyz="0x"+IpAddressOct+"U";
unsigned int iStart=atoi(xyz.c_str());
sprintf (buff, "%d.%d.%d.%d", iStart >> 24, (iStart >> 16) & 0xff,(iStart >> 8) & 0xff, iStart & 0xff);
printf ("%s\n", buff);
return 0;
}
The output I am getting is 0.0.0.0, but expected output is 239.191.200.69
atoi() only takes integers. If you call atoi("1"), it will return 1. If you call atoi("a"), it will return 0.
What you should do is create a mapping between hex values and do the calculation every two character. The following is an example:
1 #include <map>
2 #include <iostream>
3 #include <cstring>
4 #include <string>
5 #include <vector>
6
7 using namespace std;
8
9 static std::map<unsigned char, int> hexmap;
10
11 void init() {
12 hexmap['0'] = 0;
13 hexmap['1'] = 1;
14 hexmap['2'] = 2;
15 hexmap['3'] = 3;
16 hexmap['4'] = 4;
17 hexmap['5'] = 5;
18 hexmap['6'] = 6;
19 hexmap['7'] = 7;
20 hexmap['8'] = 8;
21 hexmap['9'] = 9;
22 hexmap['a'] = 10;
23 hexmap['A'] = 10;
24 hexmap['b'] = 11;
25 hexmap['B'] = 11;
26 hexmap['c'] = 12;
27 hexmap['C'] = 12;
28 hexmap['d'] = 13;
29 hexmap['D'] = 13;
30 hexmap['e'] = 14;
31 hexmap['E'] = 14;
32 hexmap['f'] = 15;
33 hexmap['F'] = 15;
34 }
35
36 vector<int> parseIp(string income) {
37 vector<int> ret;
38 if (income.size() > 8)
39 // if incoming string out of range
40 return ret;
41 int part = 0;
42 char buf[4];
43 for (int i = 0; i < income.size(); ++i) {
44 part += hexmap[income[i]];
45 cout << income[i] << " " << hexmap[income[i]] << " " << part << endl;
46 if ((i % 2) == 1) {
47 ret.push_back(part);
48 part = 0;
49 } else {
50 part *= 16;
51 }
52 }
53
54 return ret;
55 }
56
57 int main(void) {
58 init();
59 string ipAddressOct = "EFBFC845";
60 vector<int> ip = parseIp(ipAddressOct);
61 cout << ip[0] << "." << ip[1] << "." << ip[2] << "." << ip[3] << endl;
62 }
The above could be overly complicated. It is intended for example only.
This is a function in c++ that takes a HEX string and converts it to its equivalent ASCII character.
string HEX2STR (string str)
{
string tmp;
const char *c = str.c_str();
unsigned int x;
while(*c != 0) {
sscanf(c, "%2X", &x);
tmp += x;
c += 2;
}
return tmp;
If you input the following string:
537461636b6f766572666c6f77206973207468652062657374212121
The output will be:
Stackoverflow is the best!!!
Say I were to input 1,000,000 unique HEX strings into this function, it takes awhile to compute.
Is there a more efficient way to complete this?
Of course. Look up two characters at a time:
unsigned char val(char c)
{
if ('0' <= c && c <= '9') { return c - '0'; }
if ('a' <= c && c <= 'f') { return c + 10 - 'a'; }
if ('A' <= c && c <= 'F') { return c + 10 - 'A'; }
throw "Eeek";
}
std::string decode(std::string const & s)
{
if (s.size() % 2) != 0) { throw "Eeek"; }
std::string result;
result.reserve(s.size() / 2);
for (std::size_t i = 0; i < s.size() / 2; ++i)
{
unsigned char n = val(s[2 * i]) * 16 + val(s[2 * i + 1]);
result += n;
}
return result;
}
Just since I wrote it anyway, this should be fairly efficient :)
const char lookup[32] =
{0,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0};
std::string HEX2STR(std::string str)
{
std::string out;
out.reserve(str.size()/2);
const char* tmp = str.c_str();
unsigned char ch, last = 1;
while(*tmp)
{
ch <<= 4;
ch |= lookup[*tmp&0x1f];
if(last ^= 1)
out += ch;
tmp++;
}
return out;
}
Don't use sscanf. It's a very general flexible function, which means its slow to allow all those usecases. Instead, walk the string and convert each character yourself, much faster.
This routine takes a string with (what I call) hexwords, often used in embedded ECUs, for example "31 01 7F 33 38 33 37 30 35 31 30 30 20 20 49" and transforms it in readable ASCII where possible.
Transforms by taking care of the discontuinity in the ASCII table (0-9: 48-57, A-F:65 - 70);
int i,j, len=strlen(stringWithHexWords);
char ascii_buffer[250];
char c1, c2, r;
i=0;
j=0;
while (i<len) {
c1 = stringWithHexWords[i];
c2 = stringWithHexWords[i+1];
if ((int)c1!=32) { // if space found, skip next section and bump index only once
// skip scary ASCII codes
if (32<(int)c1 && 127>(int)c1 && 32<(int)c2 && 127>(int)c2) {
//
// transform by taking first hexdigit * 16 and add second hexdigit
// both with correct offset
r = (char) ((16*(int)c1+((int)c2<64?((int)c2-48):((int)c2-55))));
if (31<(int)r && 127>(int)r)
ascii_buffer[j++] = r; // check result for readability
}
i++; // bump index
}
i++; // bump index once more for next hexdigit
}
ascii_bufferCurrentLength = j;
return true;
}
The hexToString() function will convert hex string to ASCII readable string
string hexToString(string str){
std::stringstream HexString;
for(int i=0;i<str.length();i++){
char a = str.at(i++);
char b = str.at(i);
int x = hexCharToInt(a);
int y = hexCharToInt(b);
HexString << (char)((16*x)+y);
}
return HexString.str();
}
int hexCharToInt(char a){
if(a>='0' && a<='9')
return(a-48);
else if(a>='A' && a<='Z')
return(a-55);
else
return(a-87);
}