0
votes

I want to convert unsigned char to hex (using unsigned int). This is my code so far. I have a program1 that produces an unsigned char array and the other program2 only takes in only hex (using unsigned int), so what i want to achieve is getting an input of unsigned char array and converting that array into hex.

(E.g., program1 outputs "1234567812345678", program2 should output "31323334353637383132333435363738")

Sorry if this question seems dumb. Looked around for answers here but it didn't seem to be what I wanted.

uint64_t phex (unsigned char[16], long);



int main (void) {

int i;
unsigned char key[16] = "1234567812345678";


uint64_t* keyHex = phex(key,16); //store into an array here

for(i = 0; i < 16; i++)
printf("%.2x ", keyHex[i]);

free(keyHex);

return 0;

}


uint64_t phex(unsigned char* string, long len)
{

int i;
//allocate memory for your array
uint64_t* hex = (uint64_t*)malloc(sizeof(uint64_t) * len);

for(i = 0; i < len; ++i) {
    //do char to int conversion on every element of char array
    hex[i] = string[i] - '0';
}

//return integer array
return hex;

}
4
0x1234567812345678 in hexadecimal is ‭1311768465173141112‬ in decimal. I don't know where you get 31323334353637383132333435363738. Maybe you want to convert binary data to hexadecimal string representation?Barmak Shemirani
@BarmakShemirani i want to convert 1234567812345678(decimal) to hexadecimal, which is 31323334353637383132333435363738.vivola

4 Answers

2
votes

If all you need to do is print the values, then you do not need to do any conversion. Just use printf %.2xon the original array.

int main (void) {
    int i;
    unsigned char key[16] = "1234567812345678";
    for(i = 0; i < 16; i++)
        printf("%.2x", key[i]);
    return 0;
}

Even if you want to use the array in some other function, the actual bytes stored in key are the ascii characters, i.e. 0x31 0x32 etc. You can generally directly use the array key

Edit: To store the output in a character array, you can use the sprintf function.

char hex[33];
for(i = 0; i < 16; i++)
    sprintf(hex+2*i, "%.2x", key[i]);

Also note that the original array key should be 17 bytes to account for the \0 at the end.

1
votes

Here is my take on it - the phex() function converts any data in memory into a newly allocated string containing the hex representation.

The main() function shows an example usage. The output is "31323334353637383930" for the example data.

#include <stdlib.h> /* malloc() */
#include <stdio.h>  /* sprintf() */
#include <string.h> /* strlen(), in the example main() */

/*
 * Return a hex string representing the data pointed to by `p`,
 * converting `n` bytes.
 *
 * The string should be deallocated using `free()` by the caller.
 */
char *phex(const void *p, size_t n)
{
    const unsigned char *cp = p;              /* Access as bytes. */
    char *s = malloc(2*n + 1);       /* 2*n hex digits, plus NUL. */
    size_t k;

    /*
     * Just in case - if allocation failed.
     */
    if (s == NULL)
        return s;

    for (k = 0; k < n; ++k) {
        /*
         * Convert one byte of data into two hex-digit characters.
         */
        sprintf(s + 2*k, "%02X", cp[k]);
    }

    /*
     * Terminate the string with a NUL character.
     */
    s[2*n] = '\0';

    return s;
}

/*
 * Sample use of `phex()`.
 */
int main(void)
{
    const char *data = "1234567890";               /* Sample data */
    char *h = phex(data, strlen(data));  /* Convert to hex string */

    if (h != NULL)
        puts(h);                                  /* Print result */

    free(h);                             /* Deallocate hex string */
    return 0;
}
0
votes

I see the function signature as

 uint64_t phex (unsigned char[16], long);

so I think, you do not need array of uint64_t to transform one string, representing one number (perhaps I am wrong and you want to transform each single character from its char-representation to int and show as hexadecimal number).

First, let's consider the following code to transformation in decimal (actually, number in your example - 1234567812345678 - looks like decimal number):

uint64_t phex(unsigned char* string, long len)
{

    int i;
    //you do not need to allocate memory for array
    uint64_t hex = 0; // just one variable

    for (i = 0; i < len; ++i) {
        hex *= 10; // shift
        hex += string[i] - '0'; // add to the smallest rank
    }

    //return integer Value
    return hex;

}

Then for hexadecimal the program will be:

#include <stdio.h>
#include <stdint.h>
#include <string.h>
uint64_t phex(unsigned char[16], long);

int main(void) {

    int i;
    unsigned char key[16] = "A123B00CF1";


    uint64_t keyHex = phex(key, strlen(key));

    printf("%lld(dec) = %llx(hex)", keyHex, keyHex);

    return 0;
}


uint64_t phex(unsigned char* string, long len)
{
    int i;
    uint64_t hex = 0;
    for (i = 0; i < len; ++i) {
        hex *= 0x10; // shift for one hexadecimal digit
        // -'0' for digits 0..9 and -('A'-10) for digits `A`..`F`
        hex += toupper(string[i]) - ((string[i] >= 'A') ? ('A' - 10) : '0');
        // TODO: Consider making check for characters that are not hexadecimal
        // e.g. use isxdigit(string[i]) in some if statement
    }
    return hex;
}

Note: There is a mistake in your example code - uint64_t* keyHex take the value from function that returns uint64_t (not pointer ``uint64_t*`), but if you accept my idea, you do not need pointer at all.

0
votes

If the task is to transform chars ('1', '2', etc.) to their hexadecimal representation (31 for '1', 32 for '2', etc.) it is hard to understand why you need uint64_t.

But for your task code can be as follows (without uint64_t):

#include <stdio.h>
#include <string.h>

unsigned int * phex(unsigned char[16], long);

int main(void) {
    int i;
    unsigned char key[16] = "1234567812345678";
    unsigned* keyHex = phex(key, strlen(key)); // strlen(key) to determine number of characters 
    for (i = 0; i < 16; i++)
        printf("%.2x", keyHex[i]); // you do need space as I see from your example
    free(keyHex);
    return 0;

}


unsigned int * phex(unsigned char* string, long len)
{
    int i;
    //allocate memory for array
    unsigned int * hex = (unsigned int *)malloc(sizeof(unsigned int) * len);
    for (i = 0; i < len; ++i) {
        //no special conversion needed
        hex[i] = string[i];
    }
    //return array with hexadecimal representation for each character in string
    return hex;
}