trouble converting from void pointer to char pointer - c

I'm using the paillier library for cryptography.
There is a function namely paillier_ciphertext_to_bytes which converts to bytes. Upon checking the paillier.h, it has the return type void*.
I would like to take the string this generates which I believe is hex, and convert it to a decimal number using strtol.
However, when I cast the output of paillier_ciphertext_to_bytes to a char*, it doesn't work as expected.
This is my code
#include<stdio.h>
#include<stdlib.h>
#include<gmp.h>
//#include<paillier.h>
#include"paillier.h"
#include <string.h>
#include<malloc.h>
int main()
{
int n=4; //degree of polynomial
int i=0;
char* str;
paillier_pubkey_t *pub_key=(paillier_pubkey_t *)malloc(sizeof(paillier_pubkey_t));
paillier_prvkey_t *prv_key=(paillier_prvkey_t *)malloc(sizeof(paillier_prvkey_t));
paillier_keygen(4,&pub_key,&prv_key,paillier_get_rand_devrandom);
for(i=0;i<n;i++)
{
unsigned int p=rand()%20;
paillier_plaintext_t *ptext = paillier_plaintext_from_ui(p);
paillier_ciphertext_t *ctext;
ctext = paillier_enc(0, pub_key, ptext, paillier_get_rand_devrandom);
str = (char*)paillier_ciphertext_to_bytes(n,ctext);
printf("str==[%s]\n",str);
printf("number_str==[%d]\n",(int)strtol(str,NULL,16));
}
return 0;
}
This is the output I get
str==[]
number_str==[0]
str==[]
number_str==[0]
str==[]
number_str==[0]
str==[]
number_str==[0]
This is the paillier.h library code, where I looked up the signature of paillier_ciphertext_to_bytes
Side note,
I only want to convert the encryption to a number. Actually there is no reason for me to believe that paillier_ciphertext_to_bytes can be cast to a char*. So, I've also tried converting it to an int* and then print out it's value as follows
int* myintp;
myintp = (int*)paillier_ciphertext_to_bytes(n,ctext);
printf("number==[%d]\n",*myintp);
This always give me an integer number, but I'm not sure if this is correct(the decimal representation of the encrypted string)
EDIT :
As per Felix's comment, I've tried this
#include<stdio.h>
#include<stdlib.h>
#include<gmp.h>
//#include<paillier.h>
#include"paillier.h"
#include <string.h>
#include<malloc.h>
int main()
{
int n=4; //degree of polynomial
int i=0;
void* myvoid;
FILE* fp;
fp = fopen("file.txt","a");
paillier_pubkey_t *pub_key=(paillier_pubkey_t *)malloc(sizeof(paillier_pubkey_t));
paillier_prvkey_t *prv_key=(paillier_prvkey_t *)malloc(sizeof(paillier_prvkey_t));
paillier_keygen(4,&pub_key,&prv_key,paillier_get_rand_devrandom);
for(i=0;i<n;i++)
{
unsigned int p=rand()%20;
paillier_plaintext_t *ptext = paillier_plaintext_from_ui(p);
paillier_ciphertext_t *ctext;
ctext = paillier_enc(0, pub_key, ptext, paillier_get_rand_devrandom);
myvoid=paillier_ciphertext_to_bytes(PAILLIER_BITS_TO_BYTES(pub_key->bits)*2, ctext);
fwrite(myvoid, 1, PAILLIER_BITS_TO_BYTES(pub_key->bits)*2, fp);
printf("as int : %d\n",*(int*)myvoid);
printf("as str : %d\n",(int)strtol((char*)myvoid,NULL,16));
}
fclose(fp);
return 0;
}
But I get unprintable characters in my output file when I try to print myvoid, and when I cast to integer and string, I get this output
as int : 31136768
as str : 0
as int : 493106432
as str : 0
as int : 493111552
as str : 0
as int : 493092864
as str : 0

Without knowing the library in question, it's pretty clear from the name of the function what it does: It gives you the actual encrypted bytes contained in some library-specific container type. Of course you can just take it as char * (there's no need to cast and you shouldn't, but that's another question).
Typically encrypted data contains any possible byte value, which includes 0 as well as non-printable characters and so on. So, having a char * pointer to it doesn't make it a C string. What you would do now is encode it in some ascii encoding, often base64 is used. This would give you a string representation suitable for writing to a file or sending in an email.
About the part of interpreting it as an int: This is a very bad idea. As encrypted data can contain any possible byte values, it really should only be treated as this: bytes. With int you could have for example two different representations of 0, so you'd lose information. And that's just one example of what could go wrong.
char * or void * is the correct type for a sequence of arbitrary bytes. Of course, to do anything useful with it, you need to know how many bytes there are in the encrypted form. Look in your library's documentation for how to know.

Related

How can I scan a string with unknown size and values to use inside a function in C using gets()?

I am trying to convert a number from base b to base 10 using the function base_b_to_10 as below:
long int base_b_to_10(char* B, long int base) //take in the number as string returns it converted to base 10 as long int
{
long int N; //base 10 number:
N = strtol(B, NULL, base); //
return(N);
}
In the main program, the user will input the base of the input number and the input number itself.
The length and the size of the string is unknown and is up to the user to define
This is a simplified version of a big program I am trying to build in which the size of the string B is dynamically allocated in another function so I cannot do something like:
char B[100];
How to solve this? the compiler is returning nothing.
Input string (here: test) can be of any reasonable size. Anyway, there might be some limitations, see: Strtol() and atol() do not convert strings larger than 9 digits
Output string is a pointer (here: *str) to position within input string (here: test). According to this, the size of the string to which str points does not matter. (Note: In this example, str is only valid as long as test is valid).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
long int base_b_to_10(char* B, long int base, char **ret_str)
{
long int N;
N = strtol(B, ret_str, base);
return N;
}
int main()
{
long int val;
char *str;
char test[50] = "43724325HelloWorld";
val = base_b_to_10(test, 10, &str);
printf("val = %ld\n", val);
printf("str = %s\n", str);
return 1;
}
Notes: I adapted your example just to be working (not improving or simplifying anything). It is probably clear that you could also directly use strtol function in the main routine. Moreover, it does not matter, how the input string was allocated (fixed size or dynamic size) - just needs to be allocated and needs to end by \0 (as usual).
If cross platforming is not an issue, and assuming you are running on a linux system, you can make use of asprintf().
It basically formats your string and allocates the memory for you (remember to free it afterwards).
This is not part of the standard library so it has its limitations.
Another approach is to use snprintf() to preddict the size of the output buffer then and use malloc()
#include <stdio.h>
int main ()
{
int cx = snprintf ( NULL, 0, "18 characters long" );
printf("%d", cx);
return 0;
}
// OUTPUT:
// 18
Ok so I solved this problem by first using a buffer string with size 50 (pretty sufficient), than I used the strlen() function to determine the size of the string given by the user, and lastly I allocate this number to the string I will be using for the conversion:
char *str, buffer[50];
printf("enter the input value: ");
gets(buffer);
int i;
i = strlen(buffer);
str = (char*)malloc(i*sizeof(char));
strcpy(str, buffer);
fflush(stdin);
N = base_b_to_10(str, base_in);

+'0' wont give char value of int

I was trying to make this int to char program. The +'0' in the do while loop wont convert the int value to ascii, whereas, +'0' in main is converting. I have tried many statements, but it won't work in convert() .
#include<stdio.h>
#include<string.h>
void convert(int input,char s[]);
void reverse(char s[]);
int main()
{
int input;
char string[5];
//prcharf("enter int\n");
printf("enter int\n");
scanf("%d",&input);
convert(input,string);
printf("Converted Input is : %s\n",string);
int i=54;
printf("%c\n",(i+'0')); //This give ascii char value of int
printf("out\n");
}
void convert(int input,char s[])
{
int sign,i=0;
char d;
if((sign=input)<0)
input=-input;
do
{
s[i++]='0'+input%10;//but this gives int only
} while((input/=10)>0);
if(sign<0)
s[i++]='-';
s[i]=EOF;
reverse(s);
}
void reverse(char s[])
{
int i,j;
char temp;
for(i=0,j=strlen(s)-1;i<j;i++,j--)
{
temp=s[i];
s[i]=s[j];
s[j]=temp;
}
}
Output screenshot
Code screenshot
The +'0' in the do while loop wont convert the int value to ascii
Your own screenshot shows otherwise (assuming an ASCII-based terminal).
Your code printed 56, so it printed the bytes 0x35 and 0x36, so string[0] and string[1] contain 0x35 and 0x36 respectively, and 0x35 and 0x36 are the ASCII encodings of 5 and 6 respectively.
You can also verify this by printing the elements of string individually.
for (int i=0; string[i]; ++i)
printf("%02X ", string[i]);
printf("\n");
I tried your program and it is working for the most part. I get some goofy output because of this line:
s[i]=EOF;
EOF is a negative integer macro that represents "End Of File." Its actual value is implementation defined. It appears what you actually want is a null terminator:
s[i]='\0';
That will remove any goofy characters in the output.
I would also make that string in main a little bigger. No reason we couldn't use something like
char string[12];
I would use a bare minimum of 12 which will cover you to a 32 bit INT_MAX with sign.
EDIT
It appears (based on all the comments) you may be actually trying to make a program that simply outputs characters using numeric ascii values. What the convert function actually does is converts an integer to a string representation of that integer. For example:
int num = 123; /* Integer input */
char str_num[12] = "123"; /* char array output */
convert is basically a manual implementation of itoa.
If you are trying to simply output characters given ascii codes, this is a much simpler program. First, you should understand that this code here is a mis-interpretation of what convert was trying to do:
int i=54;
printf("%c\n",(i+'0'));
The point of adding '0' previously, was to convert single digit integers to their ascii code version. For reference, use this: asciitable. For example if you wanted to convert the integer 4 to a character '4', you would add 4 to '0' which is ascii code 48 to get 52. 52 being the ascii code for the character '4'. To print out the character that is represented by ascii code, the solution is much more straightforward. As others have stated in the comments, char is a essentially a numeric type already. This will give you the desired behavior:
int i = 102 /* The actual ascii value of 'f' */
printf("%c\n", i);
That will work, but to be safe that should be cast to type char. Whether or not this is redundant may be implementation defined. I do believe that sending incorrect types to printf is undefined behavior whether it works in this case or not. Safe version:
printf("%c\n", (char) i);
So you can write the entire program in main since there is no need for the convert function:
int main()
{
/* Make initialization a habit */
int input = 0;
/* Loop through until we get a value between 0-127 */
do {
printf("enter int\n");
scanf("%d",&input);
} while (input < 0 || input > 127);
printf("Converted Input is : %c\n", (char)input);
}
We don't want anything outside of 0-127. char has a range of 256 bits (AKA a byte!) and spans from -127 to 127. If you wanted literal interpretation of higher characters, you could use unsigned char (0-255). This is undesirable on the linux terminal which is likely expecting UTF-8 characters. Values above 127 will be represent portions of multi-byte characters. If you wanted to support this, you will need a char[] and the code will become a lot more complex.

Converting a binary string to integer

When I try and convert my binary string to int I am receiving a couple of mistakes that I can not figure out. First I am reading from a file and the leading zeros are not showing up when I convert and the new line is showing zero.
This code I am using from this questions: Convert binary string to hexadecimal string C
char* binaryString[100];
// convert binary string to integer
int value = (int)strtol(binaryString, NULL, 2);
//output string as int
printf("%i \n",value)
My txt file and what I am expecting as an output:
00000000
000000010001001000111010
00000000000000000000000000000001
101010111100110100110001001001000101
What I get:
0
0
70202
1
-1127017915
This line:
char* binaryString[100];
Is declaring an array of 100 char pointers (or 100 strings). You probably meant this to declare a buffer of 100 characters to be interpreted as a single string:
char binaryString[100];
char *binaryString[100];
// You are creating an array of pointers in this scenario, use char binaryString[100] instead;
int value = (int)strtol(binaryString, NULL, 2);
// 101010111100110100110001001001000101 Is a 36 bit number, int (in most implementations) is 32 bit. use long long (64 bit in visual c++) as type and strtoll as function instead.
printf("%i \n",value)
Must be printf("%lld \n", value).
In summary:
#include "stdio.h"
#include "stdlib.h" // required for strtoll
int main(void)
{
char str[100] = "101010111100110100110001001001000101";
long long val = 0;
val = strtoll(str, NULL, 2);
//output string as int
printf("%lld \n", val);
return 0;
}
if im understanding this correctly you want to take a binary string so ones and zeros and convert it to a Hex string so 0-F, if so the problem is with the Write not the Convert, you specified '%i' as the written value format, what you need to do for hex is specify '%x'
Change this "printf("%i \n",value)" to "printf("%x\n",value)"

Simple int to char[] conversion

I have a simple question
How to simply convert integer (getting values 0-8) to char, e.g. char[2] in C?
Thanks
main()
{
int i = 247593;
char str[10];
sprintf(str, "%d", i);
// Now str contains the integer as characters
}
Hope it will be helpful to you.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void main()
{
int a = 543210 ;
char arr[10] ="" ;
itoa(a,arr,10) ; // itoa() is a function of stdlib.h file that convert integer
// int to array itoa( integer, targated array, base u want to
//convert like decimal have 10
for( int i= 0 ; i < strlen(arr); i++) // strlen() function in string file thar return string length
printf("%c",arr[i]);
}
Use this. Beware of i's larger than 9, as these will require a char array with more than 2 elements to avoid a buffer overrun.
char c[2];
int i=1;
sprintf(c, "%d", i);
If you want to convert an int which is in the range 0-9 to a char, you may usually write something like this:
int x;
char c = '0' + x;
Now, if you want a character string, just add a terminating '\0' char:
char s[] = {'0' + x, '\0'};
Note that:
You must be sure that the int is in the 0-9 range, otherwise it will fail,
It works only if character codes for digits are consecutive. This is true in the vast majority of systems, that are ASCII-based, but this is not guaranteed to be true in all cases.
You can't truly do it in "standard" C, because the size of an int and of a char aren't fixed. Let's say you are using a compiler under Windows or Linux on an intel PC...
int i = 5;
char a = ((char*)&i)[0];
char b = ((char*)&i)[1];
Remember of endianness of your machine! And that int are "normally" 32 bits, so 4 chars!
But you probably meant "i want to stringify a number", so ignore this response :-)

Extract integer from char buffer

I have a very simple problem in C. I am reading a file linewise, and store it in
a buffer
char line[80];
Each line has the following structure:
Timings results : 2215543
Timings results : 22155431
Timings results : 221554332
Timings results : 2215543
What I am trying to do, is to extract the integer value from this line. Does C here provide any simple function that allows me to do that?
Thanks
Can use sscanf per line, like:
#include <stdio.h>
int time = -1;
char* str = "Timings results : 120012";
int n = sscanf(str, "Timings results : %d", &time);
in this case n == 1 means success
Yes - try atoi
int n=atoi(str);
In your example, you have a fixed prefix before the integer, so you could simply add an offset to szLine before passing it to atoi, e.g.
int offset=strlen("Timings results : ");
int timing=atoi(szLine + offset);
Pretty efficient, but doesn't cope well with lines which aren't as expected. You could check each line first though:
const char * prefix="Timings results : ";
int offset=strlen(prefix);
char * start=strstr(szLine, prefix);
if (start)
{
int timing=atoi(start+offset);
//do whatever you need to do
}
else
{
//line didn't match
}
You can also use sscanf for parsing lines like this, which makes for more concise code:
int timing;
sscanf(szLine, "Timings results : %d", &timing);
Finally, see also Parsing Integer to String C for further ideas.

Resources