How to convert unsigned int(u16) into string value(char *)? - c

I need to convert u16(unsigned int -2 byte) value into string (not ascii).
How to convert unsigned int(u16) into string value(char *)?

/* The max value of a uint16_t is 65k, which is 5 chars */
#ifdef WE_REALLY_WANT_A_POINTER
char *buf = malloc (6);
#else
char buf[6];
#endif
sprintf (buf, "%u", my_uint16);
#ifdef WE_REALLY_WANT_A_POINTER
free (buf);
#endif
Update: If we do not want to convert the number to text, but to an actual string (for reasons that elude my perception of common sense), it can be done simply by:
char *str = (char *) (intptr_t) my_uint16;
Or, if you are after a string that is at the same address:
char *str = (char *) &my_uint16;
Update: For completeness, another way of presenting an uint16_t is as a series of four hexadecimal digits, requiring 4 chars. Skipping the WE_REALLY_WANT_A_POINTER ordeal, here's the code:
const char hex[] = "0123456789abcdef";
char buf[4];
buf[0] = hex[my_uint16 & f];
buf[1] = hex[(my_uint16 >> 4) & f];
buf[2] = hex[(my_uint16 >> 8) & f];
buf[3] = hex[my_uint16 >> 12];

A uint16_t value only requires two unsigned char objects to describe it. Whether the higher byte comes first or last depends on the endianness of your platform:
// if your platform is big-endian
uint16_t value = 0x0A0B;
unsigned char buf[2];
buf[0] = (value >> 8); // 0x0A comes first
buf[1] = value;
// if your platform is little-endian
uint16_t value = 0x0A0B;
unsigned char buf[2];
buf[0] = value;
buf[1] = (value >> 8); // 0x0A comes last

It's not entirely clear what you want to do, but it sounds to me that what you want is a simple cast.
uint16_t val = 0xABCD;
char* string = (char*) &val;
Beware that the string in general is not a 0-byte terminated C-string, so don't do anything dangerous with it.

You can use sprintf:
sprintf(str, "%u", a); //a is your number ,str will contain your number as string

Related

unsigned characters and sprintf() C

I have this code:
int main(){
char buffer[1024];
char port = 1;
int length = 255;
char * record = "$TAG ,0 ,89 ,0, 1\n";
if(length < 0 || length > 255){
printf("Error - length out of range for an unsigned char.\n");
exit(1);
}
snprintf(buffer, 1024, "%c%c%s", port, (unsigned char) length, record);
int port_rc = buffer[0];
int length_rc = buffer[1];
printf("port_rc: %d\n",port_rc);
printf("length_rc: %d\n",length_rc);
return 0;
}
Output when I run it:
port_rc: 1
length_rc: -1
I think I am missing something here in terms of snprintf() as i'm not seeing the 255 value when reading the array it created back. My guess is that snprintf() is promoting the variable 'length' to an int or something. Does anyone know how I can achieve this?
Thanks.
I don't think you can use sprintf() to store 255 into the buffer. The buffer argument to sprintf() is a char array. Whether char is signed or unsigned by default is implementation-defined; see Is char signed or unsigned by default?. If 255 is greater than CHAR_MAX, trying to store 255 results in undefined behavior; if the implementation defaults to signed then CHAR_MAX will probably be 127.
I suggest not using sprintf() to store numbers into the buffer. Declare it as:
unsigned char buffer[127];
Then you can do:
buffer[0] = port;
buffer[1] = length;
snprintf((char *)(buffer + 2), sizeof buffer - 2, "%s", record);
"Be careful, though," when judging such a "solution."
In my humble, the root problem – in your original post - is that the variables port_rc and length_rc should have been declared as unsigned integers. You do not want a value such as $FF to be erroneously "sign-extended" to become $FFFFFFFF == -1 ...
Your "solution" is quite different from the original because, as you see, it now stores into both buffer[0] and buffer[1] before then retrieving and examining those values!
WORKING SOLUTION:
int main(){
unsigned char buffer[1024];
char port = 1;
int length = 255;
char * record = "$TAG ,0 ,89 ,0, 1\n";
if(length < 0 || length > 255){
printf("Error - length out of range for an unsigned char.\n");
exit(1);
}
buffer[0] = port;
buffer[1] = length;
snprintf((char *)(buffer), sizeof buffer - 2, "%c%c%s", port,length,record);
int port_rc = buffer[0];
int length_rc = buffer[1];
char char_first = buffer[2];
printf("port_rc: %d\n",port_rc);
printf("length_rc: %d\n",length_rc);
printf("char_first: %c\n",char_first);
return 0;
}
RETURNS:
port_rc: 1
length_rc: 255
char_first: $

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

Validation system for openssl hmac code using nist vector values as input

I have wrote a c code which takes the input value of key and message makes call to openssl hmac functions and generate result of mac code.
Input values are collected from NIST Test Vectors
#define KEY_SIZE 11 // in bytes
#define MSG_SIZE 129 // in bytes
#include <stdio.h>
#include <string.h>
#include <openssl/hmac.h>
void str2hex(char *, char*, int);
int main() {
char *key, *msg;
unsigned char keyy[KEY_SIZE], msgt[MSG_SIZE], temp[4];
unsigned char* result;
unsigned int i, len = 20,Tlen = 10;
key = "";//values specified below
msg ="";//values specified below
/*CONVERT STRING TO HEX DIGITS - KEY*/
str2hex(key, keyy, KEY_SIZE);
//CONVERT STRING TO HEX DIGITS - MSG*//
str2hex(msg, msgt, MSG_SIZE);
result = (unsigned char*)malloc(sizeof(char) * len);
HMAC_CTX ctx;
HMAC_CTX_init(&ctx);
HMAC_Init_ex(&ctx, keyy, strlen(keyy), EVP_sha1(), NULL);
HMAC_Update(&ctx, (unsigned char*)&msgt, strlen(msgt));
HMAC_Final(&ctx, result, &len);
HMAC_CTX_cleanup(&ctx);
printf("HMAC digest: ");
for (i = 0; i < Tlen; i++)
printf("%02x", result[i]);
printf("\n");
free(result);
return 0;
}
//===================== string to hex conversion
================================//
void str2hex(char *str, char *hex, int len) {
int tt, ss;
unsigned char temp[4];
for (tt = 0, ss = 0; tt < len, ss < 2 * len; tt++, ss += 2) {
temp[0] = '0';
temp[1] = 'x';
temp[2] = str[ss];
temp[3] = str[ss + 1];
hex[tt] = (int) strtol(temp, NULL, 0);
}
}
//---------------------------------------------------------------------------------//
The first input given:
Key = 82f3b69a1bff4de15c33
Msg = fcd6d98bef45ed6850806e96f255fa0c8114b72873abe8f43c10bea7c1df706f10458e6d4e1c9201f057b8492fa10fe4b541d0fc9d41ef839acff1bc76e3fdfebf2235b5bd0347a9a6303e83152f9f8db941b1b94a8a1ce5c273b55dc94d99a171377969234134e7dad1ab4c8e46d18df4dc016764cf95a11ac4b491a2646be1
Output generated:
HMAC digest: 1ba0e66cf72efc349207
Nist_Mac = 1ba0e66cf72efc349207
It matches so success
But for the Second input
Key = 4766e6fe5dffc98a5c50
Msg = d68b828a153f5198c005ee36c0af2ff92e84907517f01d9b7c7993469df5c21078fa356a8c9715ece2414be94e10e547f32cbb8d0582523ed3bb0066046e51722094aa44533d2c876e82db402fbb00a6c2f2cc3487973dfc1674463e81e42a39d9402941f39b5e126bafe864ea1648c0a5be0a912697a87e4f8eabf79cbf130e
Output generated:
HMAC digest: ca96f112a79882074b63
Nist_Mac = 007e4504041a12f9e345
Its failing.If any one could check my code and kindly let me know what am i doing wrong it will be really helpfull.
You have two issues here.
The first is that you're using strlen on an array of characters that may contain a null byte. Since this function counts the number of bytes until it find a null byte, you won't get what you expect if your array contains a null byte (as is the case for your second example).
Instead of using strlen on the byte array to determine the length, use the actual length of the data. Since you're converting a string containing hex digits to bytes, the length of the byte array is half the length of the input string.
HMAC_Init_ex(&ctx, keyy, strlen(key)/2, EVP_sha1(), NULL);
HMAC_Update(&ctx, msgt, strlen(msg)/2);
Note also that you should pass msgt to HMAC_Update, not &msgt, as the latter is a pointer to an array.
The second issue is in your str2hex function. When you construct temp, you don't have enough space for a terminating null byte. This causes strtol, which expects a null-terminated string, to read past the end of the array. This invokes undefined behavior.
In this particular case you're "lucky" that it works, as the byte in memory that follows temp happens to contain either a null byte or a non-digit. You can't however depend on this behavior. Fix this by making temp one byte longer and explicitly setting that byte to 0. And while you're at it, you should also fix the signed / unsigned mismatch in your function arguments and change the type of temp to an unsigned char array.
void str2hex(char *, unsigned char*, int);
...
void str2hex(char *str, unsigned char *hex, int len) {
int tt, ss;
char temp[5];
for (tt = 0, ss = 0; tt < len, ss < 2 * len; tt++, ss += 2) {
temp[0] = '0';
temp[1] = 'x';
temp[2] = str[ss];
temp[3] = str[ss + 1];
temp[4] = 0;
hex[tt] = strtol(temp, NULL, 0);
}
}
At byte position 58 in the message, you have a 0x00 byte (null). Since you're doing an strlen(msgt), this results in 58 instead of 128. Excerpt from the documentation (emphasis mine):
The C library function size_t strlen(const char *str) computes the length of the string str up to, but not including the terminating null character.
Just use the proper length of the message and don't use string operations on char arrays that do not contain printable bytes.

Convert char pointer to unsigned char array

I want to convert a char pointer to a unsigned char var, I thought I could do that with just casting but it doesn't work:
char * pch2;
//Code that puts something in pc2
part1 = (unsigned char) pch2;
I've the code to this:
result.part1 = (unsigned char *) pch2;
printf("STRUCT %s\n",result.part1);
result is just a struct with unsigned char arrays.
EDIT:
pch2 = strtok( ip, "." );
while( pch2 != NULL ){
printf( "x %d x: %s\n", i, pch2 );
pch2[size-1] = '\0';
if(i == 1)
result.part1 = (unsigned char *) pch2;
if(i == 2)
result.part2 = (unsigned char *) pch2;
if(i == 3)
result.part3 = (unsigned char *) pch2;
if(i == 4)
result.part4 = (unsigned char *) pch2;
i++;
pch2 = strtok (NULL,".");
}
printf("STRUCT %c\n",result.part1);
Struct:
typedef struct
{
unsigned char part1;
unsigned char part2;
unsigned char part3;
unsigned char part4;
} res;
you cast to unsigned char not unsigned char* you forgot the *
part1 = (unsigned char*) pch2;
if pch2 is not null terminated the program will crash, if you're lucky, when you use strlen, so you need to null terminate it first before printing using pch2, try this instead:
pch2[size-1] = '\0'; /* note single quote */
result.part1 = (unsigned char *) pch2;
Update: define your structure like so:
typedef struct
{
const char *part1;
const char *part2
const char *part3;
const char *part4;
} res;
And assign to it without casting at all:
result.part1 = pch2;
You want to do this:
part1 = (unsigned char*) pch2;
Instead of:
part1 = (unsigned char) pch2;
Try something like this:-
char *ph2;
unsigned char *new_pointer = (unsigned char*) ph2;
I want to convert a char pointer to a unsigned char var
Are you sure? Converting pointer to char to unsigned char is not going to do any good - value will get truncated to 1 byte, and it will be meaningless anyway. Maybe you want to dereference a pointer and get value pointed by it - then you should do something like this:
unsigned char part1 = (unsigned char)*pch2;
After your edit I see that part1 is character array - if your program crashes after it is used, you probably fill pch2 incorrectly. Maybe you forgot '\0' terminator?
EDIT:
You see, it is much better now to answer your question having all required information. Do you need to use strtok? Would this be good?
res result;
char* ip = "123.23.56.33";
sscanf(ip, "%hhu.%hhu.%hhu.%hhu", &result.part1, &result.part2, &result.part3, &result.part4);
Found the problem, forgot to cast the char pch2 to unsigned int and then I can printout with %u.
Code:
unsigned int temp;
temp = atoi(pch2);
result.part1 = temp;
printf("Struct: %u\n",result.part1);
Thanks for your help guys!

Searching for 2 consecutive hex values in a char array of a file

I've read a file into an array of characters using fread. Now I want to search that array for two consecutive hex values, namely FF followed by D9 (its a jpeg marker signifying end of file). Here is the code I use to do that:
char* searchBuffer(char* b) {
char* p1 = b;
char* p2 = ++b;
int count = 0;
while (*p1 != (unsigned char)0xFF && *p2 != (unsigned char)0xD9) {
p1++;
p2++;
count++;
}
count = count;
return p1;
}
Now I know this code works if I search for hex values that don't include 0xFF (eg 4E followed by 46), but every time I try searching for 0xFF it fails. When I don't cast the hex values to unsigned char the program doesn't enter the while loop, when I do the program goes through all the chars in the array and doesn't stop until I get an out of bounds error. I'm stumped, please help.
Ignore count, its just a variable that helps me debug.
Thanks in advance.
Why not use memchr() to find potential matches?
Also, make sure you're dealing with promotions of potentially signed types (char may or may not be signed). Note that while 0xff and 0xd9 have the high bit set when looked at as 8-bit values, they are non-negative integer constants, so there is no 'sign extension' that occurs for them:
char* searchBuffer(char* b) {
unsigned char* p1 = (unsigned char*) b;
int count = 0;
for (;;) {
/* find the next 0xff char */
/* note - this highlights that we really should know the size */
/* of the buffer we're searching, in case we don't find a match */
/* at the moment we're making it up to be some large number */
p1 = memchr(p1, 0xff, UINT_MAX);
if (p1 && (*(p1 + 1) == 0xd9)) {
/* found the 0xff 0xd9 sequence */
break;
}
p1 += 1;
}
return (char *) p1;
}
Also, note that you really should be passing in some notion of the size of the buffer being searched, in case the target isn't found.
Here's a version that takes a buffer size paramter:
char* searchBuffer(char* b, size_t siz) {
unsigned char* p1 = (unsigned char*) b;
unsigned char* end = p1 + siz;
for (;;) {
/* find the next 0xff char */
p1 = memchr(p1, 0xff, end - p1);
if (!p1) {
/* sequnce not found, return NULL */
break;
}
if (((p1 + 1) != end) && (*(p1 + 1) == 0xd9)) {
/* found the 0xff 0xd9 sequence */
break;
}
p1 += 1;
}
return (char *) p1;
}
You are falling foul of integer promotions. Both operands for != (and similar) are promoted to int. And if at least one of them is unsigned, then both of them are treated as unsigned (actually that isn't 100% accurate, but for this particular situation, it should suffice). So this:
*p1 != (unsigned char)0xFF
is equivalent to:
(unsigned int)*p1 != (unsigned int)(unsigned char)0xFF
On your platform, char is evidently signed, in which case it can never take on the value of (unsigned int)0xFF.
So try casting *p1 as follows:
(unsigned char)*p1 != 0xFF
Alternatively, you could have the function take unsigned char arguments instead of char, and avoid all the casting.
[Note that on top of all of this, your loop logic is incorrect, as pointed out in various comments.]
4E will promote itself to a positive integer but *p1 will be negative with FF, and then will be promoted to a very large unsigned value that will be far greater than FF.
You need to make p1 unsigned.
You can write the code a lot shorter as:
char* searchBuffer(const char* b) {
while (*b != '\xff' || *(b+1) != '\xd9') b++;
return b;
}
Also note the function will cause a segmentation fault (or worse, return invalid results) if b does not, in fact, contain the bytes FFD9.
use void *memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen);
which is available in string.h and easy to use.
char* searchBuffer(char* b, int len)
{
unsigned char needle[2] = {0xFF, 0XD9};
char * c;
c = memmem(b, len, needle, sizeof(needle));
return c;
}

Resources