How to turn a hex string into an unsigned char array? - c

For example, I have a cstring "E8 48 D8 FF FF 8B 0D" (including spaces) which needs to be converted into the equivalent unsigned char array {0xE8,0x48,0xD8,0xFF,0xFF,0x8B,0x0D}. What's an efficient way to do this? Thanks!
EDIT: I can't use the std library... so consider this a C question. I'm sorry!

This answers the original question, which asked for a C++ solution.
You can use an istringstream with the hex manipulator:
std::string hex_chars("E8 48 D8 FF FF 8B 0D");
std::istringstream hex_chars_stream(hex_chars);
std::vector<unsigned char> bytes;
unsigned int c;
while (hex_chars_stream >> std::hex >> c)
{
bytes.push_back(c);
}
Note that c must be an int (or long, or some other integer type), not a char; if it is a char (or unsigned char), the wrong >> overload will be called and individual characters will be extracted from the string, not hexadecimal integer strings.
Additional error checking to ensure that the extracted value fits within a char would be a good idea.

You'll never convince me that this operation is a performance bottleneck.
The efficient way is to make good use of your time by using the standard C library:
static unsigned char gethex(const char *s, char **endptr) {
assert(s);
while (isspace(*s)) s++;
assert(*s);
return strtoul(s, endptr, 16);
}
unsigned char *convert(const char *s, int *length) {
unsigned char *answer = malloc((strlen(s) + 1) / 3);
unsigned char *p;
for (p = answer; *s; p++)
*p = gethex(s, (char **)&s);
*length = p - answer;
return answer;
}
Compiled and tested. Works on your example.

Iterate through all the characters.
If you have a hex digit, the number is (ch >= 'A')? (ch - 'A' + 10): (ch - '0').
Left shift your accumulator by four bits and add (or OR) in the new digit.
If you have a space, and the previous character was not a space, then append your current accumulator value to the array and reset the accumulator back to zero.

If you know the length of the string to be parsed beforehand (e.g. you are reading something from /proc) you can use sscanf with the 'hh' type modifier, which specifies that the next conversion is one of diouxX and the pointer to store it will be either signed char or unsigned char.
// example: ipv6 address as seen in /proc/net/if_inet6:
char myString[] = "fe80000000000000020c29fffe01bafb";
unsigned char addressBytes[16];
sscanf(myString, "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx
%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx", &addressBytes[0],
&addressBytes[1], &addressBytes[2], &addressBytes[3], &addressBytes[4],
&addressBytes[5], &addressBytes[6], &addressBytes[7], &addressBytes[8],
&addressBytes[9], &addressBytes[10], addressBytes[11],&addressBytes[12],
&addressBytes[13], &addressBytes[14], &addressBytes[15]);
int i;
for (i = 0; i < 16; i++){
printf("addressBytes[%d] = %02x\n", i, addressBytes[i]);
}
Output:
addressBytes[0] = fe
addressBytes[1] = 80
addressBytes[2] = 00
addressBytes[3] = 00
addressBytes[4] = 00
addressBytes[5] = 00
addressBytes[6] = 00
addressBytes[7] = 00
addressBytes[8] = 02
addressBytes[9] = 0c
addressBytes[10] = 29
addressBytes[11] = ff
addressBytes[12] = fe
addressBytes[13] = 01
addressBytes[14] = ba
addressBytes[15] = fb

use the "old" sscanf() function:
string s_hex = "E8 48 D8 FF FF 8B 0D"; // source string
char *a_Char = new char( s_hex.length()/3 +1 ); // output char array
for( unsigned i = 0, uchr ; i < s_hex.length() ; i += 3 ) {
sscanf( s_hex.c_str()+ i, "%2x", &uchr ); // conversion
a_Char[i/3] = uchr; // save as char
}
delete a_Char;

For a pure C implementation I think you can persuade sscanf(3) to do what you what. I believe this should be portable (including the slightly dodgy type coercion to appease the compiler) so long as your input string is only ever going to contain two-character hex values.
#include <stdio.h>
#include <stdlib.h>
char hex[] = "E8 48 D8 FF FF 8B 0D";
char *p;
int cnt = (strlen(hex) + 1) / 3; // Whether or not there's a trailing space
unsigned char *result = (unsigned char *)malloc(cnt), *r;
unsigned char c;
for (p = hex, r = result; *p; p += 3) {
if (sscanf(p, "%02X", (unsigned int *)&c) != 1) {
break; // Didn't parse as expected
}
*r++ = c;
}

The old C way, do it by hand ;-) (there is many shorter ways, but I'm not golfing, I'm going for run-time).
enum { NBBYTES = 7 };
char res[NBBYTES+1];
const char * c = "E8 48 D8 FF FF 8B 0D";
const char * p = c;
int i = 0;
for (i = 0; i < NBBYTES; i++){
switch (*p){
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
res[i] = *p - '0';
break;
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
res[i] = *p - 'A' + 10;
break;
default:
// parse error, throw exception
;
}
p++;
switch (*p){
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
res[i] = res[i]*16 + *p - '0';
break;
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
res[i] = res[i]*16 + *p - 'A' + 10;
break;
default:
// parse error, throw exception
;
}
p++;
if (*p == 0) { continue; }
if (*p == ' ') { p++; continue; }
// parse error, throw exception
}
// let's show the result, C style IO, just cout if you want C++
for (i = 0 ; i < 7; i++){
printf("%2.2x ", 0xFF & res[i]);
}
printf("\n");
Now another one that allow for any number of digit between numbers, any number of spaces to separate them, including leading or trailing spaces (Ben's specs):
#include <stdio.h>
#include <stdlib.h>
int main(){
enum { NBBYTES = 7 };
char res[NBBYTES];
const char * c = "E8 48 D8 FF FF 8B 0D";
const char * p = c;
int i = -1;
res[i] = 0;
char ch = ' ';
while (ch && i < NBBYTES){
switch (ch){
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
ch -= '0' + 10 - 'A';
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
ch -= 'A' - 10;
res[i] = res[i]*16 + ch;
break;
case ' ':
if (*p != ' ') {
if (i == NBBYTES-1){
printf("parse error, throw exception\n");
exit(-1);
}
res[++i] = 0;
}
break;
case 0:
break;
default:
printf("parse error, throw exception\n");
exit(-1);
}
ch = *(p++);
}
if (i != NBBYTES-1){
printf("parse error, throw exception\n");
exit(-1);
}
for (i = 0 ; i < 7; i++){
printf("%2.2x ", 0xFF & res[i]);
}
printf("\n");
}
No, it's not really obfuscated... but well, it looks like it is.

Related

How to convert a character into a number

I have a homework problem. It requires me to convert a word into uppercase and several characters have to be converted to decimal for example :
"Hello my NamE is FeLix" --> "H3LL0 MY N4M3 15 F3L1X". So, these characters had to be converted :
I = 1
S = 5
E = 3
O = 0
A = 4
etc.
How to convert it? I already tried to convert it to capslock but i cannot convert it into decimal.
I already tried to convert the words into uppercase, but have no idea how to convert the character into numbers.
int main()
{
char sentence[200];
int sentencelength = strlen(sentence);
// Ambil data user
scanf("%s",&sentence); getchar();
// Cek satu persatu pake for
for (int i= 1; i <= sentencelength; i++) {
if(sentence[i] >= 'a' && sentence[i] <= 'z') {
char uppercase = sentence[i] + 'A' - 'a';
printf("%c",uppercase);
}
}
getchar();
return 0;
}
There is no error, but I just have no idea how to convert it.
You can use switch as below.
switch(uppercase ) {
case 'I':
uppercase = '1';
break;
case 'S':
uppercase = '5';
break;
case 'E':
uppercase = '3';
break;
…
}
C arrays start at index 0, not 1, so change the for loop bounds to:
for (int i = 0; i < sentencelength; i++) {
You can use toupper (declared by #include <ctype.h>) to convert a character from lowercase to uppercase, leaving non-alphabetic characters alone. It is only defined for values representable by an unsigned char or for the value EOF.
char l33t = sentence[i];
if (l33t == (unsigned char)l33t)
l33t = toupper(l33t);
You can use a switch statement to replace certain uppercase letters with digits:
switch (l33t) {
case 'I':
l33t = '1';
break;
case 'S':
l33t = '5';
break;
case 'E':
l33t = '3';
break;
case 'O':
l33t = '0';
break;
case 'A':
l33t = '4';
break;
}
Rather than using scanf to read a whole word of input into a buffer, an alternative is to read the input a character at a time. Here is an example program that behaves as a filter:
#include <stdio.h>
#include <ctype.h>
static int convert(int ch)
{
if (ch == (unsigned char)ch)
ch = toupper(ch);
switch (ch) {
case 'I': ch = '1'; break;
case 'S': ch = '5'; break;
case 'E': ch = '3'; break;
case 'O': ch = '0'; break;
case 'A': ch = '4'; break;
}
return ch;
}
int main(void)
{
int ch;
while ((ch = getchar()) != EOF) {
ch = convert(ch);
putchar(ch);
}
return 0;
}
The above will convert the whole input until it sees end-of-file. To terminate after a single line, just add a check for a newline character to break out of the while loop.
create an array of characters: [4BCD3F....Z]
and an array of sources: [abcd...z]
run on your string, replace each character found in index I with the same character in the first array, if it's not found return the character as is.
crude, simple, works
Also, if someone complain on the calculation complexity, since you have fixed number of letters in the arrays A to Z , the complexity is O(N*M) when M is const, hence O(N) anyway

Can memory be the issue?

I was solving a question this is my code its working perfect on my local Work space with the below input and gives the expected output but in hacker rank it is a time out for compilation .
The problem statement is
In the given string:
occurs two times.
and occur one time each.
The remaining digits and don't occur at all.
Sample Input 1: lw4n88j12n1
Sample Output 1 : 0 2 1 0 1 0 0 0 2 0
Facing Issue with below input
Input:
9139f793308o0lo66h6vc13lgc697h0f6c32lu84445972k0o0l033od17c083yn5051d6j319hyo8j939n28d913015ns6zx5653x01211x12ch2526o65sg7xw6302141q9203s22l336319ll9yx4b597mr318a7943906750j4u152067nq83ne9f24thu96yd05173l47c803roxci45615f0w53i1sz913jj6za733l73tw6r66mq6p44sfhjr26h8e801z8zlcx2l1e65r2879xj3w3acv216196uq158o663y7oz2i5378v0v5w17762451t424352m23026r9o202i9785382o159e4gu1c8561157z5f1vqs5755465b8u728u956434mv944885li456628a994u7j5278m269n1pk8e46940q834h06il6h447888tr7ig72z10fe09k5g98h9bgt6z40v42s16pt6k3l3v45i83i01b9448g554741w766f2q7v31i085488h060e710p53076c6nm98pi946g8j2n6j8x29qa1ad48172y0u4818121p686bud89741201p54087u56g8scerv9pvhuo09re477zfb224i2c1325bj58jx4bk7b009f6446j5i95474p266i503r670n631x6940gwl71ejbx47imx576129248901765rnpu6l80084t0j1839f5y3409w2n403fu6ogw1170jmb6o5l520vg0703e0
Expected Output: 53 54 47 48 54 52 63 46 49 46
Thanks for the help in advance.
int main() {
int i;
int value;
char x;
int arr[10] = {0};
char * ptr =(char *)malloc(sizeof(char *));
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
scanf("%s",ptr);
while(*ptr != '\0')
{
if(*ptr >= 65 && *ptr <=90 || *ptr >=97 && *ptr <=122){
*ptr++;
}
else{
x = *ptr;
value = atoi(&x);
switch (value)
{
case 0:
arr[0]++;
*ptr++;
break;
case 1:
arr[1]++;
*ptr++;
break;
case 2:
arr[2]++;
*ptr++;
break;
case 3:
arr[3]++;
*ptr++;
break;
case 4:
arr[4]++;
*ptr++;
break;
case 5:
arr[5]++;
*ptr++;
break;
case 6:
arr[6]++;
*ptr++;
break;
case 7:
arr[7]++;
*ptr++;
break;
case 8:
arr[8]++;
*ptr++;
break;
case 9:
arr[9]++;
*ptr++;
break;
}
}
}
for(i=0;i<=9;i++)
{
printf("%d ",arr[i]);
}
return 0;
}
Here is error: char * ptr =(char *)malloc(sizeof(char *));
sizeof(char *) Equal 4 or 8. You allocated memory for example 8 chars. When you write entire STDIN to ptr then you will overwrite memory on heap.
When you read from stdin you MUST specify max length example:
char str[256] = {'\0'}
scanf ("%255s",str); //Read max 255 chars
About your body of loop, this is better :)
uint8_t digit;
if (*ptr >= '0' && *ptr <= '9')
{
digit = (uint8_t)(*ptr - '0');
if (digit < 10)
{
arr[digit]++;
}
}
ptr++; //THERE IS NO STAR *
But you should use simple for with know length and
if (ptr[i] == '\0') break;
Hope it's helps.
Edit:
sizeof(char*) is 4 or 8 as suggested #dbush.

Need help finishing C program calculator with command line arguments

This program just needs to be able to identify the invalid arguments such as having a letter in the command line or a double operator, except 5--5 that would give you 10. Order of operations does not matter it just reads left to right. The code below only give a 0005 if the first argument is a 5, I cannot figure out how to get the code to do the operations. Thank you for any input as this will definitely help me.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int op = 0;
int num1 = 0;
int num2 = 0;
double result = 0;
for (int x = 1; x < argc; x++) {
int num = atof(argv[x]);
if (num ==! argv[x]) {
printf("Invalid Input");
}
switch (atoi(argv[x])) {
case'+':
op = 43; /* ASCII value of '+' */
break;
case'-':
op = 45; /* ASCII value of '-' */
break;
case'*':
op = 42; /* ASCII value of '*' */
break;
case'/':
op = 47; /* ASCII value of '/' */
break;
case'^':
op = 94; /* ASCII value of '^' */
break;
default:
if (op == 0) {
num1 = atof(argv[x]);
} else {
switch(op){
case 43:
printf("%.1d + %.1d = %.1d",num1, num2, num1+num2);
break;
case 45:
printf("%.1d - %.1d = %.1d",num1, num2, num1-num2);
break;
case 42:
printf("%.1d * %.1d = %.1d",num1, num2, num1*num2);
break;
case 47:
printf("%.1d / %.1d = %.1d",num1, num2, num1/num2);
break;
case 94:
printf("%.4d ^ %.4d = %.4d",num1, num2, num1/num2);
break;
default:
break;
}
}
}
}
return 0;
}

convert particular array elements as integer value

I have declared an array char Buffer[100]="01 05 01 4A 63 41"; now the array looks like this
Buffer[0]='0'
Buffer[1]='1'
Buffer[2]=' '
Buffer[3]='0'
Buffer[4]='5'
i just want to convert these value to int `eg.:
Buffer[0]='0', Buffer[1]='1' to 0x01 (1)
Buffer[0]='0', Buffer[1]='5' to 0x05 (5)
... etc.
atoi()cannot be used since it converts all the Buffer value as integer.
How to convert a particular space delimited value sub-string to an integer?
My first solution works only for integers, and the following one works also for hexadecimal numbers. I wrote down the function which converts string representation of a hexadec. number into a decimal number. Then, as suggested by Jochim Pileborg, I used strtok to parse the given Buffer array.
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int hexToInt(char *tok)
{
int i,out=0, tens=1, digit;
for(i=strlen(tok)-1; i>=0; i--)
{
switch(tok[i])
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': digit=tok[i]-'0';
break;
case 'A': digit=10; break;
case 'B': digit=11; break;
case 'C': digit=12; break;
case 'D': digit=13; break;
case 'E': digit=14; break;
case 'F': digit=15; break;
}
out+=digit*tens;
tens*=16;
}
// printf("hex:%s int:%d ", tok, out);
return out;
}
int main()
{
char Buffer[100]="01 2A 10 15 20 25";
int intarr[100],current=0;
char *tok=malloc(20*sizeof(char));
tok=strtok(Buffer," ");
while(tok!=NULL)
{
intarr[current]=hexToInt(tok);
current++;
tok=strtok(NULL," ");
}
printf("\n");
}
You can treat Buffer as a string (which it is), and use e.g. strtok to "tokenize" the numbers on space boundary. Then use strtol to convert each "token" to a number.
But do note that strtok modifies the string, so if you don't want that you have to make a copy of the original Buffer and work on that copy.
Also note that as the numbers seems to be hexadecimal you can't use atoi because that function only parses decimal numbers. You have to use strtol which can handle any base from 2 to 36.
Consider this:
#include <stdio.h>
int main()
{
char Buffer[100] = "01 05 01 4A 63 41" ;
const char* h = &Buffer[0] ;
int i ;
while( *h != 0 )
{
if( sscanf( h, "%2x", &i ) == 1 )
{
printf( "0x%02X (%d)\n", i, i ) ;
}
h += 3 ;
}
return 0;
}
The output from which is:
0x01 (1)
0x05 (5)
0x01 (1)
0x4A (74)
0x63 (99)
0x41 (65)
I have assumed that all the values are hexadecimal, all two digits, and all separated by a single space (or rather a single non-hex-difgit character), and that the array is nul terminated. If either of these conditions are not true, the code will need modification. For example if the values may be variable length, then the format specifiers need changing, and, you should increment h until a space or nul is found, and if a space is found, increment once more.
You could write similar code using strtol() instead of sscanf() for conversion, but atoi() is specific to decimal strings, so could not be used.
If you are uncomfortable with the pointer arithmetic, then by array indexing the equivalent is:
#include <stdio.h>
int main()
{
char Buffer[100] = "01 05 01 4A 63 41" ;
int c = 0 ;
int i ;
while( *h != 0 )
{
if( sscanf( &Buffer[c], "%2x", &i ) == 1 )
{
printf( "0x%02X (%d)\n", i, i ) ;
}
c += 3 ;
}
return 0;
}
and the strtol() version if you prefer:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char Buffer[100] = "01 05 01 4A 63 41" ;
const char* h = &Buffer[0] ;
while( *h != 0 )
{
int i = strtol( h, 0, 16 ) ;
printf( "0x%02X (%d)\n", i, i ) ;
h += 3 ;
}
return 0;
}
You can use sscanf for this, e.g.:
int intarr[6];
sscanf(Buffer,"%d %d %d %d %d %d",&intarr[0],&intarr[1],&intarr[2],&intarr[3],&intarr[4],&intarr[5]);
You can cast Buffer[i] to int.
Then check its value, which will be in ASCII.
48->0
.
.
57->9
You can even compare the char to its ASCII value without casting
int CharToDigit(char c)
{
if(c>=48 && c<=57) // or as suggested if(c>='0' && c <='9')
return (int)c - 48; // subtract the ascii of 0
return -1; // not digit
}
For digits from A to F you'll have to subtract 55 from uppercase letters (65-10, 65 is ascii of A)
Then loop through the chars in Buffer sending them to the function: CharToDigit(Buffer[i]) and check the returned int.

Convert hex char[] to int[] in C 2 chars in 1 byte

I am trying to convert a char[] in hexadecimal format to int[] in hexadecimal.
Something like this:
hello --> 68656C6C6F --> [68, 65, 6C, 6C, 6F]
This is my code:
#include <stdio.h>
#include <string.h>
uint8_t* hex_decode(unsigned char *in, size_t len, uint8_t *out);
int main(void){
unsigned char word_in[17], word_out[33];//17:16+1, 33:16*2+1
int i, len = 0;
uint8_t* out;
while(len != 16){
printf("Set new word:");
fgets( word_in, sizeof( word_in), stdin);
len = strlen( word_in);
if( word_in[len-1]=='\n')
word_in[--len] = '\0';
for(i = 0; i<len; i++){
sprintf(word_out+i*2, "%02X", word_in[i]);
}
if(len != 16){
printf("Please, use a word of 16 chars long\n\n");
}
}
printf("%s", word_in);
printf("\n");
hex_decode(word_out, sizeof(word_out), out);
return 0;
}
uint8_t* hex_decode(unsigned char *in, size_t len, uint8_t *out)
{
unsigned int i, t, hn, ln;
for (t = 0,i = 0; i < len; i+=2,++t) {
hn = in[i] > '9' ? (in[i]|32) - 'a' + 10 : in[i] - '0';
ln = in[i+1] > '9' ? (in[i+1]|32) - 'a' + 10 : in[i+1] - '0';
out[t] = (hn << 4 ) | ln;
printf("%s",out[t]);
}
return out;
}
But after printing the word, I got a segmentation fault.
That function works perfect in arduino so I think it should works fine at my computer... Where is the problem?
See #dasblinkenlight answer for seg fault. To decode 2 bytes:
My 50 Cent... (a short version)
char hex[3];
char * phex;
int result;
for(int i = 0; i < 256; i++)
{
sprintf(hex, "%02X", i);
phex = hex;
result = ((*phex > 64 ? (*phex & 0x7) + 9 : *phex - 48) << 4) | (*(phex+1) > 64 ? (*(phex+1) & 0x7) + 9 : *(phex+1) - 48);
if(result != i)
{
printf("err %s %02X\n", hex, result);
}
}
Code above does no validation. This procedure returns -1 when input was invalid.
int h2i(char * ph)
{
int result;
if(*ph > 96 && *ph < 103) result = *ph - 87;
else if(*ph > 64 && *ph < 71) result = *ph - 55;
else if(*ph > 47 && *ph < 59) result = *ph - 48;
else return -1;
result <<= 4;
ph++;
if(*ph > 96 && *ph < 103) result |= *ph - 87;
else if(*ph > 64 && *ph < 71) result |= *ph - 55;
else if(*ph > 47 && *ph < 59) result |= *ph - 48;
else return -1;
return result;
}
But wait? A char can also be -1. Yes, after casting.
char * x = "FF";
char y;
int result;
result = h2i(x);
// if (result == -1) ...error...
y = (char)result;
You get a segmentation fault because you are passing the pointer out before making any assignments to it. Either the hex_decode need to take uint8_t **out_ptr and assign it a dynamically allocated array, or the caller needs to provide an array sufficient to hold the output of the conversion.
The reason why it "works" on another platform is that it exhibits undefined behavior: in arduino, the arbitrary value placed in the uninitialized pointer out happens to point to an unused location in memory. Writing to that location does not trigger segmentation fault, creating an illusion of working code.
i will just share my own code for this:
it converts any 8 hexadecimal char string into a integer number from [-2147483648. 2147483647]
input(argument) is 1 string(8+'\0'), output(returns) is a long int, MODIFY AS NECESSARY
#define N 8
long int hex2dec(char* hex){ /*conversor HEX 2 DEC*/
int i,j,n[N],l,neg;
long int dec=0;
for(i=0;i<N;i++){
n[i]=0;
}
l=strlen(hex);
neg=0;
if(hex[0]>='8'){
neg=1;
for(i=0;i<N;i++){
if(hex[i]=='0'){
hex[i]='F';
continue;
}
if(hex[i]=='1'){
hex[i]='E';
continue;
}
if(hex[i]=='2'){
hex[i]='D';
continue;
}
if(hex[i]=='3'){
hex[i]='C';
continue;
}
if(hex[i]=='4'){
hex[i]='B';
continue;
}
if(hex[i]=='5'){
hex[i]='A';
continue;
}
if(hex[i]=='6'){
hex[i]='9';
continue;
}
if(hex[i]=='7'){
hex[i]='8';
continue;
}
if(hex[i]=='8'){
hex[i]='7';
continue;
}
if(hex[i]=='9'){
hex[i]='6';
continue;
}
if(hex[i]=='A'){
hex[i]='5';
continue;
}
if(hex[i]=='B'){
hex[i]='4';
continue;
}
if(hex[i]=='C'){
hex[i]='3';
continue;
}
if(hex[i]=='D'){
hex[i]='2';
continue;
}
if(hex[i]=='E'){
hex[i]='1';
continue;
}
if(hex[i]=='F'){
hex[i]='0';
continue;
}
}
}
for(i=0;i<N;i++){
switch(hex[i]){
case '0':
n[i]=hex[i]-48; /* Ascii '0'=48 48-48=0*/
break;
case '1':
n[i]=hex[i]-48; /* Ascii '1'=49 49-48=1*/
break;
case '2':
n[i]=hex[i]-48;
break;
case '3':
n[i]=hex[i]-48;
break;
case '4':
n[i]=hex[i]-48;
break;
case '5':
n[i]=hex[i]-48;
break;
case '6':
n[i]=hex[i]-48;
break;
case '7':
n[i]=hex[i]-48;
break;
case '8':
n[i]=hex[i]-48;
break;
case '9':
n[i]=hex[i]-48;
break;
case 'A':
n[i]=hex[i]-55; /* Ascii 'A'=65 65-55=10*/
break;
case 'B':
n[i]=hex[i]-55; /* Ascii 'B'=66 66-55=11*/
break;
case 'C':
n[i]=hex[i]-55;
break;
case 'D':
n[i]=hex[i]-55;
break;
case 'E':
n[i]=hex[i]-55;
break;
case 'F':
n[i]=hex[i]-55;
break;
}
}
for(i=0,j=l;i<l;i++,j--){
dec=dec+(n[j-1]*pow(16,i));
}
if(neg==1){
dec=0-dec;
dec=dec-1;
}
return dec;
}
change
uint8_t *out;//region is not ensured
to
uint8_t out[sizeof(word_out)/2];
change
hex_decode(word_out, sizeof(word_out), out);//sizeof(word_out) is 33, must to 32
to
hex_decode(word_out, strlen(word_out), out);//strlen(word_out) or len * 2 or sizeof(word_out) -1
change
printf("%s",out[t]);//out is not string
to
printf("%02X ",out[t]);
The program looks complicated comparing what you want to do.
if you want to print the hexadecimal ascii code of a charachter, you can simply use
printf("%02X",'K'); // this will display the code ascii of 'K' in hexadecimal
If you want to print your word in code ascii in another char array. you can use sprintf():
int main() {
char word_in[17]="hello", word_out[33];
char *pi = word_in, *po = word_out;
word_out[0]=0;
for (;*pi;po+=2,pi++)
sprintf(po,"%02X",*pi);
printf("%s\n", word_out);
}
A charachetr is saved in binary format in the memory. this binary format represent the code ascii of the charachter. And when you want to print its content:
when using "%d": this will print the code ascii as integer
when using "%x": this will print the code ascii as hexadecimal
when using "%c": this will print the charachter

Resources