So i have this function which receives a pointer:
int myfunc( const char *token, unsigned char *plaintext )
I do my stuff and i end up with a char array:
unsigned char my_plaintext[1024];
Now i need to set that pointer (plaintext) to what's in my_plaintext.
I've tried many different ways but i haven't yet figure this one out...
This part is in a cpp file, and i've even tried:
std::string tmpstr( my_plaintext );
But this comes back with:
token_crypto.cpp:131:13: error: invalid conversion from 'char*' to 'unsigned char*' [-fpermissive]
my_plaintext
^~~~~~~~~~~~
And
std::string tmpstr( (char *)my_plaintext );
'�5�B'
this does compiles but the content is all wrong:
EDIT:
The content of my_plaintext is fine:
int myfunc( const char *token, unsigned char *plaintext ) {
unsigned char my_plaintext[1024];
... some processing stuff (specifically gcm_decrypt) to which is pass my_plaintext ...
cout << my_plaintext
// prints: hello:world
but then however i try set the contents of plaintext to whatever is in my_plaintext either fails at compilation or prints some weird characters.
If you know that plaintext already points at an array that is 1024 long (or longer) then you can use memmove():
int myfunc( const char *token, unsigned char *plaintext )
{
unsigned char my_plaintext[1024];
/* ... fill in my_plaintext here ... */
memmove(plaintext, my_plaintext, 1024);
/* ... rest of function ... */
}
Note that the parameters to memmove are destintation and then source rather than the other way round.
It's up to the caller of your function to make sure the pointer they pass in points to at least 1024 bytes.
You can use memcpy() instead in this case, but using memmove() is good practice in general.
The C++ string constructor doesn't take an unsigned char *. See the C++ reference here:
http://www.cplusplus.com/reference/string/string/string/
You need to cast the unsigned char array to a char array. See how to do that here:
How to Convert unsigned char* to std::string in C++?
Related
I'm playing with an Arduino board and the samples provided. Trying to get a message I received to be displayed on the LCD. I'm struggling to figure out how to work with some of the pre-built code.
I get the error: invalid conversion from 'const unsigned char*' to 'const char*
I tried modify the payload parameter type but it breaks other references to MessageCallback.
Screen.print() definition in the documentation for the arduino board:
int print(unsigned int line, const char s, bool wrap)
Code:
static int MessageCallback(const unsigned char *payload)
{
int result = 200;
const char screenMsg[100];
strcpy(screenMsg,"Set Temp: ");
strcat(screenMsg,payload);
Screen.print(1, screenMsg, true);
return result;
}
Strcat's arguments are (char *, const char *). You can cast "payload" to a char* by doing "strcat(screenMsg, (char*)payload);". Read Strcat two unsigned char in C.
If you just change to char screenMsg[100]; it should work.
The print function will not change the string you provide to it, is all that
const char s
means.
I am working in a c++ project where I have to use < openssl/sha.h> and I am using in particular the SHA1 function. My problem is, that the function receives unsigned char[], and I need to get processed parameters passed as arguments to the program:
int main(int argc, char* argv[])
{
unsigned char message[] = argv[1];
/* program continues using message */
}
And the error I am getting is the following:
error: array initializer must be an initializer list or string literal
const unsigned char message[] = argv[1];
^
So I am not getting to cast appropiately the argument input to the 'message' variable, to make the appropiate call to SHA1 function.
Thanks!!
An array cannot be initialized from a pointer. You should probably use an unsigned char * instead:
unsigned char *message = reinterpret_cast<unsigned char *>(argv[1]);
I have an encryption function declared as follows: int encrypt(unsigned char* keydata, int keydata_len, unsigned char *plaintext, int plaintext_len, unsigned char *ciphertext). This works perfectly and now I call it according to the given snippet.
const char *password = "password";
len = encrypt(password, (int)strlen(password), (unsigned char*)(content.c_str()), (int)strlen(content.c_str()), ciphertext);
On compiling the C++ code I get an error as:
crest.cc:52:13: error: no matching function for call to 'encrypt'
len = encrypt(password, (int)strlen(password), (unsigned char*)(content.c_str()), (int)strlen(content.c_str()), ciphertext);
^~~~~~~
./aes.h:10:5: note: candidate function not viable: no known conversion from 'const char *' to 'unsigned char *' for 1st argument
int encrypt(unsigned char* keydata, int keydata_len, unsigned char *plaintext, int plaintext_len, unsigned char *ciphertext);
What is the correct way to typecast in C++ to get around this error ?
There are several problems with this code, and the only (correct) way to fix them is to ensure that you use the correct data types in the first place.
So, instead of const char *password = "password", use unsigned char password[] = "password"; (of course, this will probably give you trouble with strlen, since it won't like unsigned char) - using sizeof(password)-1 will work in THIS instance, but is ill advised as a general solution, since password may well be not be directly available as an array - not sure quite what you should do as an "ideal" solution, really.
Now, the question can be asked whether it is actually correct to have a non-const input to the function. If you have the source for encrypt, you may want to change the function to encrypt(const unsigned char* keydata, size_t keydata_len, const unsigned char* plaintext, size_t plaintext_len, unsigned char* ciphertext) - still doesn't fix the problem with strlen of unsigned char of course, but it's what I'd expect the prototype to be for a function like this.
An alternative would be to rewrite the encrypt function to make casts to unsigned only internally, and use char * inputs (with const where relevant).
Note that it's NOT valid to cast away constness EXCEPT for cases where you know that the original content is not const (which I think is NOT guaranteed to be the case for std::string::c_str(), but std::string::data() should work)
This question already has answers here:
Can I turn unsigned char into char and vice versa?
(6 answers)
Closed 8 years ago.
I am using visual studio 2010 with CLR(Common language Run Time).
I want to return unsigned char * from compress function to main function but both unsigned char * and char * giving erro
"Error 7 error C2440: '=' : cannot convert from 'char *' to 'unsigned char *' F:\4-2\Thesis\PROJECT\Database Compression Main\Database Compression 2\db_comp_main.cpp 21 "
unsigned char* compressor(char *data)
{
unsigned char *compressed_string;
//With some process I had compressed string of data variable as unsigned char* in variable compressed_string successfully and also printed here. Now want to return it from here.
return compressed_string;
}
int main()
{
unsigned char *main_data;
main_data=compressor("Muhammad Ashikuzzaman.Student from Khulna University Of Engineering And Technology from Bangladesh");// When I click the error from error list the cursor is put here beside str by visual studio.
printf("%s",main_data);
}
Need to return unsigned char * type data from compressor function. Please help.
Change any of the data type (function argument *data or local variable *main_data) to match the type. Try this
unsigned char *main_data;
Or....
Simple type casting will work to make it working anyway:
unsigned char* compressor(char *data)
{
unsigned char *compressed_string;
compressed_string = (unsigned char*) data;
return compressed_string;
}
int main()
{
char *main_data;
main_data=(char*) compressor("Muhammad Ashikuzzaman.Student from Khulna University Of Engineering And Technology from Bangladesh");
printf("%s",main_data);
}
Or...
(Changing everything with char*)
There are three char types: (plain) char, signed char and unsigned char. Any char is usually an 8-bit integer* (There's no dedicated "character type" in C language) and in that sense, a signed and unsigned char have a useful meaning (generally equivalent to uint8_t and int8_t). When used as a character in the sense of text, use a char (also referred to as a plain char). This is typically a signed char but can be implemented either way by the compiler. So I think using char* is safe here.
Working Example (considering char * as data type):
char* compressor(char *data)
{
char *compressed_string;
compressed_string = "compressed";
// compressed_string = data;
return compressed_string;
}
int main()
{
char *main_data;
main_data=compressor("Muhammad Ashikuzzaman.Student from Khulna University Of Engineering And Technology from Bangladesh");
printf("%s",main_data);
}
Also, for simplicity you can use pointer to pointer
void compressor(char **data) {
*data = "compressed"; // assuming the compressed data will be smaller in length of main data, so buffer overflow won't occur
}
int main() {
char *main_data = "Muhammad Ashikuzzaman.Student from Khulna University Of Engineering And Technology from Bangladesh";
compressor(&main_data);
printf("%s", main_data);
return 0;
}
Edit
As you asked an alternative to pass by reference, There is no way except pass by reference regarding passing array as function argument. Because when you will write void func(char str[]) you may think you're performing pass by value. But g++ compiler will optimize the statement as void func(char &str[0]) to avoid coping the whole array as function parameter. So in all scenario, you are actually passing by reference.
Here you have to allocate the memory storage for the string. The pointer only point address a not any sequence of byte like array.You have to use calloc or malloc for C and new for C++ to allocate the required memory address. use typecasting to convert the char* to unsigned char*.
#include <bits\stdc++.h>
unsigned char* compressor(unsigned char *data)
{
unsigned char *compressed_string = new unsigned char[100];
//With some process I had compressed string of data variable as unsigned unsigned char** in variable compressed_string successfully and also printed here. Now want to return it from here.
compressed_string = (unsigned char*)"working";
return compressed_string;
}
int main()
{
unsigned char *main_data = new unsigned char[1000];
main_data=compressor((unsigned char*)"Muhammad Ashikuzzaman.Student from Khulna University Of Engineering And Technology from Bangladesh");// When I click the error from error list the cursor is put here beside str by visual studio.
printf("%s",main_data);
}
you can use memory as required using a different input variable to avoid unnecessary dynamic allocation.
#include <bits\stdc++.h>
unsigned char* compressor(unsigned char *data) {
unsigned char *compressed_string = new unsigned char[strlen((char*)data)+1];
//With some process I had compressed string of data variable as unsigned char* in variable compressed_string successfully and also printed here. Now want to return it from here.
compressed_string = (unsigned char*)"working";
return compressed_string;
}
int main() {
unsigned char *inp = new unsigned char[1000];
inp = (unsigned char*)"Muhammad Ashikuzzaman.Student from Khulna University Of Engineering And Technology from Bangladesh";
unsigned char *main_data = new unsigned char[strlen((char*)inp)+1];
main_data = compressor(inp);
printf("%s",main_data);
}
In a C++-program I have a char* pointing to the beginning of an array containing BUFFER_SIZE number of chars (each char the size of one byte).
I now want to use that code in an NS3-simulation, which packets takes as input a uint8_t const* , pointing to a buffer.
What should I do in order to create a 'uint8_t const*' which points at the first mentioned buffer?
You must either use reinterpret_cast:
int main () {
char buffer[10];
reinterpret_cast<unsigned char const *>(buffer);
}
or use a C-style cast:
int main () {
char buffer[10];
(unsigned char const *)buffer;
}