简体   繁体   中英

Converting unsigned char array to hex

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.

(Eg, 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;

}

If all you need to do is print the values, then you do not need to do any conversion. Just use printf %.2x on 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, ie 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.

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;
}

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.

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;
}

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM