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);
Related
I've finished some C Programming book and felt confident enough to try the cryptopals exercises. I wanted to call a libsodium function which excepts pointers to char arrays I can't figure out.
Could you tell me what is (obviously) wrong with my code and guide me a to a topic I can review to understand my problem?
int main() {
unsigned char hex[] = "49276d206b696c6c696e6720796f757220627261696e206c696b652061207069736f6e6f7573206d757368726f6f6d";
const char *phex = hex;
const size_t phex_length = sizeof(hex);
unsigned char end[phex_length];
const char ** const hex_end = &phex;
printf("Using this hex string with size %ld bytes: \n %s \n",phex_length, **phex);
unsigned char bin[phex_length*10];
unsigned char * const pbin;
size_t binsize = sizeof(bin);
printf("sizeof result for bin: %d \n", binsize);
int status = sodium_hex2bin(pbin, binsize, phex, phex_length, NULL, NULL, hex_end);
if(status < 0) {
printf("Error %d target: bin seems not large enoughi \n", status);
return 1;
}
printf("Converted Binary is: %d \n",bin);
return 0;
}
The functions signature of libsodium I try to call (https://libsodium.gitbook.io/doc/helpers)
int sodium_hex2bin(unsigned char * const bin, const size_t bin_maxlen,
const char * const hex, const size_t hex_len,
const char * const ignore, size_t * const bin_len,
const char ** const hex_end);
Normally you should tell us what your problem is with your code. Also what compiler warnings yout get that you were not able to fix.
All this is missing in your question, but a few issues can already be seen:
int main() {
unsigned char hex[] = "49276d206b696c6c696e6720796f757220627261696e206c696b652061207069736f6e6f7573206d757368726f6f6d";
const char *phex = hex;
const size_t phex_length = sizeof(hex);
The spec you linked tells us:
hex does not have to be nul terminated, as the number of characters to parse is supplied via the hex_len parameter.
This means you should not include the terminating 0 byte.
Also why do you make hex an array of unsigned char? It is just a string and the functions expects const char * const hex. Nothing is telling you to make it unsigned.
unsigned char end[phex_length];
const char ** const hex_end = &phex;
That is not a proper variable for the purpose it is used.
The function you call, will return the position where conversion stopped, to the caller via the end pointer. There is no point in passing the address of a char[].
printf("Using this hex string with size %ld bytes: \n %s \n",phex_length, **phex);
unsigned char bin[phex_length*10];
Where did you get the idea to allocate 10 bytes per hex digit?
Every 2 hex digits will end up in 1 binary byte.
unsigned char * const pbin;
Why make it const? That means you cannot even assign any value afterwards.
size_t binsize = sizeof(bin);
printf("sizeof result for bin: %d \n", binsize);
int status = sodium_hex2bin(pbin, binsize, phex, phex_length, NULL, NULL, hex_end);
if(status < 0) {
printf("Error %d target: bin seems not large enoughi \n", status);
return 1;
}
printf("Converted Binary is: %d \n",bin);
As mentioned in comment, bin is of wrong type for %d. And the value you are converting is way too large for any integer variable anyway.
return 0;
}
You seem to have completely misunderstood how function parameters work.
Check your textbook for passing by value and passing by reference (or passing by address)
With fixing the issues above your code should look more like that (untested):
int main(void) {
char hex[] = "49276d206b696c6c696e6720796f757220627261696e206c696b652061207069736f6e6f7573206d757368726f6f6d";
const size_t hex_length = strlen(hex);
unsigned char *end;
printf("Using this hex string with size %zu bytes: \n %s \n", hex_length, hex);
unsigned char bin[hex_length/2];
size_t maxsize = sizeof(bin);
size_t binsize;
printf("sizeof result for bin: %zu \n", binsize);
int status = sodium_hex2bin(bin, maxbinsize, hex, phex_length, NULL, &binsize, &end);
if(status < 0) {
printf("Error %d target: bin seems not large enough\n", status);
return 1;
}
printf("Converted Binary is: \n");
for (int i = 0; i < binsize; i++)
{
printf("%02hhx ", bin[i]);
}
putc('\n');
return 0;
}
I try to add a nonce to my blockchain program. But when I test a program performance by trying to repeat the result (I need to be able to do to verify my chain), I do not get an identical result.
First I have a function which transform a structure to unsigned array pointer :
struct Test{
unsigned char data[4];
unsigned char nonce[4];
unsigned char hash[32];
}*prev,*next;
unsigned char *toStringTest(struct Test data)
{
unsigned char *str=malloc(sizeof(unsigned char)*sizeof(data));
memcpy(str,&data,sizeof(data));
return str;
}
Then, I have a program which give me a hash and nonce:
In this function:
I concatenated unsigned char pointer from toStringTest() with unsigned char arrat nonce.
I calculated hash of this concatenation.
If the hash starts by 0x00 I save hash and nonce into next block. If not, I repeat the function.
void hash_with_nonce(struct Test* message,struct Test* new_message){
unsigned char nonce[4]; //number only used once
unsigned char buffer[32];
while(1){
RAND_bytes(nonce, 4); //this function puts 4 cryptographically strong pseudo-random bytes into nonce.
unsigned char* str=toStringTest(*message);
int len = sizeof(unsigned char)*sizeof(*str)+sizeof(unsigned char)*sizeof(nonce);
unsigned char* message_with_nonce = malloc(len);
memcpy(message_with_nonce,str,sizeof(*str));
memcpy(message_with_nonce+sizeof(unsigned char)*sizeof(*str),nonce,sizeof(nonce));
//I concatenated toStringTest(*message) with nonce
SHA256(message_with_nonce, sizeof(message_with_nonce), buffer); //calculation of hash
free(message_with_nonce);
unsigned char var[1] = {0x00}; //rule for nonce decision, I want what hash start by 0x00
if((int *)var[0] == (int *)buffer[0]){
memcpy(new_message->hash,buffer, 32);
memcpy(new_message->nonce, nonce,sizeof(nonce));
return;
}
}
}
This is my main:
int main(int argc, char **argv)
{
unsigned char hash[32];
prev=malloc(sizeof(struct Test));
RAND_bytes(prev->data, 4);
RAND_bytes(prev->nonce, 4);
SHA256("",sizeof(""),prev->hash);
next=malloc(sizeof(struct Test));
RAND_bytes(next->data, 4);
//I just have filled this block with random data
hash_with_nonce(prev,next);
unsigned char* str=toStringTest(*prev);
int len = sizeof(unsigned char)*sizeof(*str)+sizeof(unsigned char)*sizeof(next->nonce);
unsigned char* message_with_nonce = malloc(len);
memcpy(message_with_nonce,str,sizeof(*str));
memcpy(message_with_nonce+sizeof(unsigned char)*sizeof(*str),next->nonce,sizeof(next->nonce));
SHA256(message_with_nonce, sizeof(message_with_nonce), hash);
}
prev and next are just 2 blocks which I use to check if function hash_with_nonce is working.
A problem is that the unsigned char hash[32] of the main is not the identical to next->hash. SHA256() and RAND_bytes() are openssl functions.
To check if 2 hashs are same, I have this function:
void PrintHex(unsigned char data[], int size)
{
unsigned char tmp[size];
for (int i=0; i<size; i++)
{
sprintf(tmp, "%02x",data[i]);
printf("%s", tmp);
}
printf("\n");
}
I'm heaving a problem on printing a hash generated with OpenSSL, code (using OpenSSL):
char *computeHash(char *msg){
static char hs[20];
SHA1(msg, strlen(msg), hs);
return hs;
}
int main(){
char *text;
char *hash;
int i;
text = "test";
hash = computeHash(text);
for(i=0;i<20;i++){
printf("%02x",hash[i]);
}
return 0;
}
As returning I'm getting:
$ ./a.out ffffffa94affffff8fffffffe5ffffffccffffffb1ffffff9bffffffa61c4c0873ffffffd3ffffff91ffffffe9ffffff87ffffff982fffffffbbffffffd3
Is that any way to print it right?
Thanks,
The %02x format string is for an integer. But you are printing a character. Also, hash is a char * pointer, you probably want an unsigned char *. How about:
unsigned char *hash_ptr = (unsigned char *) hash;
for(i=0;i<20;i++){
printf("%02x", (int) hash_ptr[i]);
}
I have a simple question.
The code is really short so I just post it here
#include <stdio.h>
int main(int argc, const char * argv[])
{
long int p;
printf("FYI: address of first local varaible of main() on the function stack:%p\n",&p);
printf("Enter start address <hex notation> of dump:");
scanf("%lx",&p);
char * q;
q = (char*)p;
printf("%x\n",*q);
return 0;
}
The result of last printf, for example is ffffffc8. What if I only want to keep the last two: c8. How can I do that? I tried:
printf("%2x",*q);
and
printf("%x",*q % 256);
But neither works. Can some one help? Thanks!
To print the least-significant byte of *q in hex you could use:
printf("%02x", *q & 0xFF);
This of course assumes that q can be dereferenced.
First convert to unsigned:
unsigned char q = *(unsigned char *)(p);
printf("%02X", q);
(Otherwise, if your char is signed, the variadic default promotion converts the value to int, and the result may be negative.)
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!