Converting hex to string in C? - c

Hello I am using digi dynamic c. I am trying to convert this in to string
char readingreg[4];
readingreg[0] = 4a;
readingreg[1] = aa;
readingreg[2] = aa;
readingreg[3] = a0;
Currently when I do printf statements it has to be like this:
printf("This is element 0: %x\n", readingreg[0]);
But I want this in string so I can use printf statement like this
printf("This is element 0: %s\n", readingreg[0]);
I am essentialy sending the readingreg array over TCP/IP Port, for which I need to have it as string. I cant seem to be able to convert it into string. Thanks for your help.
Also if someone can tell me how to do each element at a time rather than whole array, that would be fine to since there will only be 4 elements.

0xaa overflows when plain char is signed, use unsigned char:
#include <stdio.h>
int main(void)
{
unsigned char readingreg[4];
readingreg[0] = 0x4a;
readingreg[1] = 0xaa;
readingreg[2] = 0xaa;
readingreg[3] = 0xa0;
char temp[4];
sprintf(temp, "%x", readingreg[0]);
printf("This is element 0: %s\n", temp);
return 0;
}

If your machine is big endian, you can do the following:
char str[9];
sprintf(str, "%x", *(uint32_t *)readingreg);
If your machine is little endian you'll have to swap the byte order:
char str[9];
uint32_t host;
host = htonl(*(uint32_t *)readingreg);
sprintf(str, "%x", host);
If portability is a concern, you should use method two regardless of your endianness.
I get the following output:
printf("0x%s\n", str);
0x4aaaaaa0

Related

I need to convert a char array to ULONGLONG (C language)

I have an array of char and I need to convert it in a ULONGLONG to use it as a MAC address.
My array is like "0X001234567890" but they are all char so if I fit them in my ULONGLONG variable (using unsigned long long cast) they are all messed up.
Is there a way to have those characters in a ULONGLONG format to fit in the address variable?
My char array is formatted as 0 in [0], X in [1], 0 in [2], ecc..
And I build it after reading some values from a file.
char prefixAddr1[30] = "0X";
char prefixAddr2[30] = "0X";
int countAddr = 1;
char addr[30] = "";
char BTaddr1[30] = "";
char BTaddr2[30] = "";
FILE *fpAddress = fopen("BTaddr.txt", "r");
while (fscanf(fpAddress, "%s", &addr) == 1){
unsigned char *r, *w;
for (w = r = addr; *r; r++){
if (*r != ':'){
*w++ = *r;
}
}
*w = '\0';
if (countAddr == 1){
strncpy(BTaddr1, addr, sizeof(addr));
}
else if (countAddr == 2){
strncpy(BTaddr2, addr, sizeof(addr));
}
countAddr++;
}
strcat(prefixAddr1, BTaddr1);
strcat(prefixAddr2, BTaddr2);
printf("Address 1: %s\n", prefixAddr1);
printf("Address 2: %s\n", prefixAddr2);
If I manually set my ULONGLONG variable and print the value with %llu I see the correct address.
typedef ULONGLONG BT_ADDR;
BT_ADDR aSddr1 = 0X001343BD0F65;
printf("Address 1: %llu\n", aSddr1);
I want my char array to have the same value as if I manually set the aSddr1 variable.
From file I read "00:12:34:56:78:90", clear the ":" and append "0X" so my final string is "0X001234567890". Everything in the first example is correct from my point of view. I only need to convert prefixAddr1 in a way that my BT_ADDR variable will be work correctly as in the second example where the output is 0X001234567890. At the moment if I do (unsigned long long)prefixAddr1; and print it I will print some random numbers.

Getting char array value from a method by using pointer.

I have been trying to get the following to work:
My goal is to use pointers in main() to access elements created in a method().
// takes in address of pointer
int method(char** input) {
char *buffer = malloc(sizeof(char)*10);
buffer[0] = 0x12;
buffer[1] = 0x34;
buffer[2] = 0xab;
*input = & buffer;
printf("%x\n", *buffer); // this prints 0x12
printf("%x\n", &buffer); // this prints address of buffer example: 0x7fffbd98bf78
printf("%x\n", *input); // this prints address of buffer
return 0;
}
int main(){
char *ptr;
method(&ptr);
printf(%p\n", ptr); // this prints address of buffer
//this does not seem to print out buffer[0]
printf(%x\n", *ptr);
}
I want to print each element of buffer values, as created by the method() by using ptr. Any suggestions on how I can go about doing this?
I am not sure if I am misunderstanding something, but I thought ptr points to address of buffer. Thus, dereferencing would give me buffer[0]?
Thank you.
This a fixed & commented version of your code. Ask in the comments if there is smth. you don't understand.
#include <stdio.h>
#include <stdlib.h>
// takes in address of pointer
//Hex: 0xab is larger than the max value of a signed char.
//Most comilers default to signed char if you don't specify unsigned.
//So you need to use unsigned for the values you chose
int method(unsigned char** input) { //<<< changed
unsigned char *buffer = malloc(sizeof(char)*10);
//Check for malloc success <<< added
if(!buffer)
exit(EXIT_FAILURE);
buffer[0] = 0x12;
buffer[1] = 0x34;
buffer[2] = 0xab;
//I recommend not to mix array notation and pointer notation on the same object.
//Alternatively, you could write:
*buffer = 0x12;
*(buffer + 1) = 0x34;
*(buffer + 2) = 0xab;
//buffer already contains the address of your "array".
//You don't want the address of that address
*input = buffer; //<<< changed (removed &)
printf("%x\n", *buffer); // this prints 0x12
//Not casting &buffer will likely work (with compiler warnings
//But it is better to conform. Either use (char *) or (void *)
//<<< added the cast for printf()
printf("%p\n", (char *)&buffer); // this prints address of buffer example: 0x7fffbd98bf78
printf("%p\n", *input); // this prints address of buffer
return 0;
}
int main(){
unsigned char *ptr;
method(&ptr);
printf("%p\n", ptr); // this prints address of buffer
//this does not seem to print out buffer[0]
for(int i = 0; i < 3; i++){
//<<< changed to obtain content of buffer via ptr for loop.
unsigned char buf_elem = *(ptr + i);
printf("buffer[%d] in hex: %x\t in decimal: %d\n", i, buf_elem, buf_elem);
}
// Don't forget to free the memory. //<<< changed
free(ptr);
}

How to use tiny-aes 128 library in c?

I would like to encrypt using tiny AES library (https://github.com/kokke/tiny-AES-c) in C for AES128.
My code is as below:
unsigned char cipher[64];
unsigned char in[] = "THJmaoeuf2jsn4jebc7ak3mUdnyHeklOYopdna/OOndu3bis/E7jTd/enasduR3h"; //64 bits
printf("Size of AES input msg: %d \n", sizeof(in));
unsigned char key[] = "Gns7AauH3dnaod=="; //16 bits
unsigned char IV[] = "vhdNaleuTHenaOlL"; //16 bits
printf("cipher(before): %x \n", cipher);
AES128_CBC_encrypt_buffer(cipher, in, 64, key, IV);
for(int n=0; n<64; n++){
printf("cipher[%d]: %x \n", n, cipher);
}
The function I am using from tiny AES 128 library is this :
void AES128_CBC_encrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv)
However, the last line of printing 'cipher' is empty. I believe it should print the cipher text of the original input after encryption. Is this the correct way to use the library? Thank you.
EDIT: I updated the code here, in which 'cipher' is now printing characters but in a strange way. It prints the same thing before and after encryption, which should not be the case. This is the same case even when I changed the 'key' and 'IV' to be 16 bits and input message 'in' as 64 bits. Here is a part of the output:
cipher(before): 20003A34
cipher[0]: 20003A34
cipher[1]: 20003A34
cipher[2]: 20003A34
.
.
cipher[63]: 20003A34
Your code has undefined behavior.
This:
unsigned char *cipher = "";
makes cipher into a pointer to a single byte with the value 0 (the string terminator). It's a bit fishy since string literals are not guaranteed to be unsigned char (they're just char which is either signed or unsigned) but I think it will build.
This doesn't give you any writeable space, since string literals are read-only, so trying to write an entire encrypted block in there will give you undefined behavior.
To fix it you need:
unsigned char in[] = "THJmaoeuf2jsn4jebc7ak3mUdnyHeklOYopdna/OOndu3bis/E7jTd/enasduR3h"; //64 bits
unsigned char cipher[sizeof in];
Also, the encrypted data is very likely not a valid C string, it can contain 0-bytes and thus won't print correctly using printf("%s", ...); anyway.
in the line:
printf("cipher[%d]: %x \n", n, cipher);
change that to be:
printf("cipher[%d]: %x \n", n, cipher[n]);
That way, each byte of the cipher is outputted instead of the address of cipher which is what you are getting.
in aes.h select 128 by
#define AES128 1
and below is a sample for Encryption & Decryption
struct AES_ctx ctx;
uint8_t key[] = "aaaaaaaaaaaaaaaa";
uint8_t iv[] = "bbbbbbbbbbbbbbbb";
uint8_t str[] = "This a sample text, Length eq 32";
printf("\n raw buffer \n");
for (int i = 0; i < 32; ++i) {
printf("%.2x", str[i]);
}
AES_init_ctx_iv(&ctx, key, iv);
AES_CBC_encrypt_buffer(&ctx, str, 32);
printf("\n Encrypted buffer\n");
for (int i = 0; i < 32; ++i) {
printf("%.2x", str[i]);
}
printf("\n Decrypted buffer\n");
AES_init_ctx_iv(&ctx, key, iv);
AES_CBC_decrypt_buffer(&ctx, str, 32);
for (int i = 0; i < 32; ++i) {
printf("%.2x", str[i]);
}
printf("\n");
*Note: there is no padding is provided so for CBC and ECB, All buffers should be multiples of 16 bytes.

Converting integer to unsigned char* (int 221 to "\xdd")

I have a function which takes unsigned char* as input.
Say for example that I have:
unsigned char* data = (unsigned char*) "\xdd";
int a = 221;
How can I convert my integer a to unsigned char* such that data and my converted a is indistinguishable?
I have tried playing around with sprintf but without any luck, I'm not sure how to handle the "\x" part.
Since 221 is not guaranteed to be a valid value for a char type, the closest thing you can do is:
int a = 221;
unsigned char buffer[10];
sprintf((char*)buffer, "%c", a);
Here's an example program and its output:
#include <stdio.h>
int main()
{
unsigned char* data = (unsigned char*) "\xdd";
int a = 221;
unsigned char buffer[10];
sprintf((char*)buffer, "%c", a);
printf("%d\n", buffer[0] == data[0]);
printf("%d\n", buffer[0]);
printf("%d\n", data[0]);
}
Output:
1
221
221
Update
Perhaps I misunderstood your question. You can also use:
int a = 221;
unsigned char buffer[10] = {0};
buffer[0] = a;
As stated the question does not make sense and is not possible - you don't actually want to convert to const char *, which is a pointer type. Instead you want to convert into an array of chars and then take the address of that array by using its name.
int x = 221;
char buf[5];
snprintf(buf, sizeof buf, "\\x%.2x", x);
/* now pass buf to whatever function you want, e.g.: */
puts(buf);

Issue sending c char* over USART

I am converting hex bytes into strings and sending them over uart to a terminal on my computer. I am receiving strange (almost correct) output and I cannot figure out why. This is all done in AVR. Here is the relevant code snippets:
while(true)
{
wan_usart_transmit_string(generateString());
}
Generate String:
char *generateString()
{
char *c = "";
char d[5];
sprintf(d, "%02X", 0x61);
c = strcat(c, d);
return c;
}
wan_usart_transmit_string:
void wan_usart_transmit_string(char * data)
{
unsigned char c = *data;
while (c)
{
while (!(UCSR0A & (1 << UDRE0)));
UDR0 = c;
c = *(++data);
}
}
Output: 61611611116111111116161161111611111111... etc...
The generateString method will eventually look ahead so many positions into a circular buffer and concatenate all of the ASCII values up to that position into a single string, which will subsequently be sent over USART. So it looks a little funky right now. This was just a test snippet to make sure it operates correctly before I made it function dynamically.
You need to allocate some memory for the string you are going to return from generateString().
Currently you are pointing c char* c = "" to a string literal and then you try to write into it causing undefined behavior.
Use malloc:
char *c = malloc(sizeof( *c )*10);
c[0] = '\0'; //nul terminate so you get an empty string
char d[5];
sprintf(d, "%02X", 0x61); //you can sprintf directly into c
c = strcat(c, d);
return c;
I was able to get the output I was looking for by using the following code in the generateString method:
char *generateString(){
char *c;
char d[5];
sprintf(d, "%02X", 0x61);
return c;
}

Resources