I found this function in some library that I would like to use but I can't figure out out to pass a std::string variable to it
----------
template<int KeyLen>
std::vector<unsigned char> key_from_string(const char (*key_str)[KeyLen]) {
std::vector<unsigned char> key(KeyLen - 1);
memcpy(&key[0], *key_str, KeyLen - 1);
return key;
}
test_encryption.cpp
const std::vector<unsigned char> key2 = plusaes::key_from_string(usr_key.c_str());
this is how i am trying to call that function
Error
test_encryption.cpp: In function 'std::__cxx11::string encrypte_string(std::__cxx11::string, std::__cxx11::string)':
test_encryption.cpp:39:82: error: no matching function for call to 'key_from_string(const char*)'
const std::vector<unsigned char> key2 = plusaes::key_from_string(usr_key.c_str()); // 16-char = 128-bit
^
In file included from test_encryption.cpp:1:
pulse.hpp:685:35: note: candidate: 'std::vector<unsigned char> plusaes::key_from_string(const char (*)[17])'
inline std::vector<unsigned char> key_from_string(const char (*key_str)[17]) {
^~~~~~~~~~~~~~~
pulse.hpp:685:35: note: no known conversion for argument 1 from 'const char*' to 'const char (*)[17]'
pulse.hpp:690:35: note: candidate: 'std::vector<unsigned char> plusaes::key_from_string(const char (*)[25])'
inline std::vector<unsigned char> key_from_string(const char (*key_str)[25]) {
^~~~~~~~~~~~~~~
pulse.hpp:690:35: note: no known conversion for argument 1 from 'const char*' to 'const char (*)[25]'
pulse.hpp:695:35: note: candidate: 'std::vector<unsigned char> plusaes::key_from_string(const char (*)[33])'
inline std::vector<unsigned char> key_from_string(const char (*key_str)[33]) {
^~~~~~~~~~~~~~~
pulse.hpp:695:35: note: no known conversion for argument 1 from 'const char*' to 'const char (*)[33]'
The function in the library only accepts pointers to string literals. Example:
std::vector<unsigned char> key = plusaes::key_from_string(&"Foo");
Here KeyLen would be deduced to 4 because the string literal consists of 'F', 'o', 'o', '\0'
You supply usr_key.c_str() to the function, which returns a const char*, and that's not a match to such a function. All template parameters must be known at compile time and KeyLen is such a parameter. It must be a compile time constant.
An alternative is to create the std::vector<unsigned char> manually:
std::vector<unsigned char> key2(usr_key.begin(), usr_key.end());
or if you want, create your own helper function:
std::vector<unsigned char> my_key_from_string(const std::string& s) {
return {s.begin(), s.end()};
}
and use it like so:
auto key2 = my_key_from_string(usr_key);
Related
For testing purposes, I want to print my public and private key which are generated on the Arduino via elliptic curve.
The relevant code looks as follows,
#include <Ed25519.h>
void setup()
{
Serial.begin(9600); // Debugging only
if (!driver.init())
Serial.println("init failed");
uint8_t privateKey[32];
uint8_t publicKey[32];
Ed25519::generatePrivateKey(privateKey);
Ed25519::derivePublicKey(publicKey, privateKey);
Serial.println(publicKey);
Serial.print(",");
Serial.write(privateKey);
}
However, it gives me the following error:
/tmp/arduino_modified_sketch_961866/ask_receiver.pde: In function 'void setup()':
ask_receiver:52: error: call of overloaded 'println(uint8_t [32])' is ambiguous
Serial.println(publicKey);
^
/tmp/arduino_modified_sketch_961866/ask_receiver.pde:5
2:29: note: candidates are:
In file included from /ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/Stream.h:26:0,
from /ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/HardwareSerial.h:29,
from /ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/Arduino.h:232,
from sketch/ask_receiver.pde.cpp:1:
/ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/Print.h:78:12: note: size_t Print::println(const String&) <near match>
size_t println(const String &s);
^
/ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/Print.h:78:12: note: no known conversion for argument 1 from 'uint8_t [32] {aka unsigned char [32]}' to 'const String&'
/ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/Print.h:79:12: note: size_t Print::println(const char*) <near match>
size_t println(const char[]);
^
/ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/Print.h:79:12: note: no known conversion for argument 1 from 'uint8_t [32] {aka unsigned char [32]}' to 'const char*'
/ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/Print.h:80:12: note: size_t Print::println(char) <near match>
size_t println(char);
^
/ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/Print.h:80:12: note: no known conversion for argument 1 from 'uint8_t [32] {aka unsigned char [32]}' to 'char'
/ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/Print.h:81:12: note: size_t Print::println(unsigned char, int) <near match>
size_t println(unsigned char, int = DEC);
^
/ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/Print.h:81:12: note: no known conversion for argument 1 from 'uint8_t [32] {aka unsigned char [32]}' to 'unsigned char'
/ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/Print.h:82:12: note: size_t Print::println(int, int) <near match>
size_t println(int, int = DEC);
^
/ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/Print.h:82:12: note: no known conversion for argument 1 from 'uint8_t [32] {aka unsigned char [32]}' to 'int'
/ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/Print.h:83:12: note: size_t Print::println(unsigned int, int) <near match>
size_t println(unsigned int, int = DEC);
^
/ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/Print.h:83:12: note: no known conversion for argument 1 from 'uint8_t [32] {aka unsigned char [32]}' to 'unsigned int'
/ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/Print.h:84:12: note: size_t Print::println(long int, int) <near match>
size_t println(long, int = DEC);
^
/ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/Print.h:84:12: note: no known conversion for argument 1 from 'uint8_t [32] {aka unsigned char [32]}' to 'long int'
/ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/Print.h:85:12: note: size_t Print::println(long unsigned int, int) <near match>
size_t println(unsigned long, int = DEC);
^
/ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/Print.h:85:12: note: no known conversion for argument 1 from 'uint8_t [32] {aka unsigned char [32]}' to 'long unsigned int'
ask_receiver:54: error: call of overloaded 'write(uint8_t [32])' is ambiguous
Serial.write(privateKey);
^
/tmp/arduino_modified_sketch_961866/ask_receiver.pde:54:28: note: candidates are:
In file included from /ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/Arduino.h:232:0,
from sketch/ask_receiver.pde.cpp:1:
/ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/HardwareSerial.h:129:20: note: virtual size_t HardwareSerial::write(uint8_t) <near match>
virtual size_t write(uint8_t);
^
/ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/HardwareSerial.h:129:20: note: no known conversion for argument 1 from 'uint8_t [32] {aka unsigned char [32]}' to 'uint8_t {aka unsigned char}'
/ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/HardwareSerial.h:130:19: note: size_t HardwareSerial::write(long unsigned int) <near match>
inline size_t write(unsigned long n) { return write((uint8_t)n); }
^
/ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/HardwareSerial.h:130:19: note: no known conversion for argument 1 from 'uint8_t [32] {aka unsigned char [32]}' to 'long unsigned int'
/ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/HardwareSerial.h:131:19: note: size_t HardwareSerial::write(long int) <near match>
inline size_t write(long n) { return write((uint8_t)n); }
^
/ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/HardwareSerial.h:131:19: note: no known conversion for argument 1 from 'uint8_t [32] {aka unsigned char [32]}' to 'long int'
/ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/HardwareSerial.h:132:19: note: size_t HardwareSerial::write(unsigned int) <near match>
inline size_t write(unsigned int n) { return write((uint8_t)n); }
^
/ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/HardwareSerial.h:132:19: note: no known conversion for argument 1 from 'uint8_t [32] {aka unsigned char [32]}' to 'unsigned int'
/ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/HardwareSerial.h:133:19: note: size_t HardwareSerial::write(int) <near match>
inline size_t write(int n) { return write((uint8_t)n); }
^
/ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/HardwareSerial.h:133:19: note: no known conversion for argument 1 from 'uint8_t [32] {aka unsigned char [32]}' to 'int'
In file included from /ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/Stream.h:26:0,
from /ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/HardwareSerial.h:29,
from /ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/Arduino.h:232,
from sketch/ask_receiver.pde.cpp:1:
/ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/Print.h:52:12: note: size_t Print::write(const char*) <near match>
size_t write(const char *str) {
^
/ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/Print.h:52:12: note: no known conversion for argument 1 from 'uint8_t [32] {aka unsigned char [32]}' to 'const char*'
/tmp/arduino_modified_sketch_961866/ask_receiver.pde: In function 'void loop()':
/tmp/arduino_modified_sketch_961866/ask_receiver.pde:80:51: warning: invalid conversion from 'uint8_t* {aka unsigned char*}' to 'const char*' [-fpermissive]
driver.printBuffer("Decrypted:", buf, strlen(buf));
^
In file included from /ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/arduino/avr/cores/arduino/Arduino.h:25:0,
from sketch/ask_receiver.pde.cpp:1:
/ogobase/home/henk/Downloads/arduino-1.8.5-linux64/arduino-1.8.5/hardware/tools/avr/avr/include/string.h:399:15: note: initializing argument 1 of 'size_t strlen(const char*)'
extern size_t strlen(const char *) __ATTR_PURE__;
^
exit status 1
call of overloaded 'println(uint8_t [32])' is ambiguous
I have also tried:
Serial.write((int)privateKey);
But it gives me gibberish output.
I also tried:
String stringOne = String(privateKey, HEX)
Serial.println(stringOne);
But it gives me the following output:
call of overloaded 'String(uint8_t [32], int)' is ambiguous
Preferably, I'd output it in HEX or some other value which I can transfer over another medium.
Solved it by using a simple for loop
uint8_t i;
for (i = 0; i < (uint8_t)(sizeof(privateKey)); i++) {
if (privateKey[i] < 0x10) { /* To print "0F", not "F" */
Serial.write('0');
}
Serial.print(privateKey[i], HEX);
}
The following code fails to compile for me (gcc 4.6.3, Ubuntu 12.04):
#include <inttypes.h>
#include <stdio.h>
static inline void adjustBuffer(const uint8_t *&buf, size_t &bufSize, size_t len)
{
buf += len;
bufSize -= len;
}
uint16_t packInt(uint8_t *&buf, size_t &bufSize, int value)
{
size_t valueSize = sizeof(int);
*reinterpret_cast<int *>(buf) = value;
adjustBuffer(buf, bufSize, valueSize);
return valueSize;
}
bool unpackInt(const uint8_t *&buf, size_t &bufSize, int &value)
{
value = *reinterpret_cast<const int*>(buf);
adjustBuffer(sizeof(int));
return true;
}
int main()
{
static const size_t BufSize = 100;
size_t bufSize = BufSize;
uint8_t buf[BufSize];
uint8_t *buf_ptr = buf;
packInt(buf_ptr, bufSize, 1);
bufSize = BufSize;
int x;
unpackInt(buf, bufSize, x);
return 0;
}
I get the following errors:
$ make CXXFLAGS="-Wall -g" ref_to_ptr
g++ -Wall -g ref_to_ptr.cpp -o ref_to_ptr
ref_to_ptr.cpp: In function ‘uint16_t packInt(uint8_t*&, size_t&, int)’:
ref_to_ptr.cpp:15:41: error: invalid initialization of reference of type ‘const uint8_t*& {aka const unsigned char*&}’ from expression of type ‘uint8_t* {aka unsigned char*}’
ref_to_ptr.cpp:5:20: error: in passing argument 1 of ‘void adjustBuffer(const uint8_t*&, size_t&, size_t)’
ref_to_ptr.cpp: In function ‘bool unpackInt(const uint8_t*&, size_t&, int&)’:
ref_to_ptr.cpp:22:29: error: invalid initialization of non-const reference of type ‘const uint8_t*& {aka const unsigned char*&}’ from an rvalue of type ‘unsigned int’
ref_to_ptr.cpp:5:20: error: in passing argument 1 of ‘void adjustBuffer(const uint8_t*&, size_t&, size_t)’
ref_to_ptr.cpp: In function ‘int main()’:
ref_to_ptr.cpp:35:30: error: invalid initialization of non-const reference of type ‘const uint8_t*& {aka const unsigned char*&}’ from an rvalue of type ‘uint8_t* {aka unsigned char*}’
ref_to_ptr.cpp:19:6: error: in passing argument 1 of ‘bool unpackInt(const uint8_t*&, size_t&, int&)’
make: *** [ref_to_ptr] Error 1
It seems the compiler has trouble assigning a reference to uint8_t* (uint8_t *&) to a const uint8_t *& (which IIRC is a reference to pointer to const). First, I don't understand why it tries to assign a pointer to uint8_t and not a reference to a pointer. Second, shouldn't the conversion work? You can convert uint8_t * to const uint8_t *, why wouldn't converting references to both types work?
Of course, adding an adjustBuffer() that takes a const uint8_t *& works, but I'd like to understand why
Passing an uint8_t * as a const uint8_t *& parameter would allow the function to replace the unint8_t * with a const uint8_t *. Now there is a const uint8_t *in the place where the caller expects a modifiable uint8_t *. This is not save, since the caller might modify the pointed-to data after the function returned.
The problem is the same as in this C++ FAQ lite section.
I am very new in c++ and want to cast a char* from a std::string to a byte*.
Here is my code:
inline string XOR(const string &value, const string &key) {
string retval(value);
CryptoPP::xorbuf(&retval[0], &key[0], retval.length());
return retval;
}
In g++, the output is:
AESXCBC128.cpp: In function ‘std::string CryptoPP::XOR(const string&, const string&)’:
AESXCBC128.cpp:79:48: error: invalid conversion from ‘char*’ to ‘byte* {aka unsigned char*}’ [-fpermissive]
xorbuf(&retval[0], &key[0], retval.length());
^
AESXCBC128.cpp:45:6: error: initializing argument 1 of ‘void CryptoPP::xorbuf(byte*, const byte*, size_t)’ [-fpermissive]
void xorbuf(byte *buf, const byte *mask, size_t count)
^
AESXCBC128.cpp:79:48: error: invalid conversion from ‘const char*’ to ‘const byte* {aka const unsigned char*}’ [-fpermissive]
xorbuf(&retval[0], &key[0], retval.length());
^
AESXCBC128.cpp:45:6: error: initializing argument 2 of ‘void CryptoPP::xorbuf(byte*, const byte*, size_t)’ [-fpermissive]
void xorbuf(byte *buf, const byte *mask, size_t count)
inline string XOR(const string &value, const string &key) {
string retval(value);
CryptoPP::xorbuf(&retval[0], &key[0], retval.length());
return retval;
}
Crypto++ typedefs a byte in confg.h:
typedef unsigned char byte;
You can use something like:
CryptoPP::xorbuf(
reinterpret_cast<byte*>(&retval[0]),
reinterpret_cast<const byte*>(&key[0]),
retval.length());
Or, you can do it with C-style casts:
CryptoPP::xorbuf((byte*)&retval[0], (const byte*)&key[0], retval.length());
Here are some similar questions for SecByteBlock, which is a byte array rather than a char array:
How to convert SecByteBlock to string?
string to SecByteBlock conversion
Here are some references on C++ casting:
When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?
Regular cast vs. static_cast vs. dynamic_cast
#include <iostream>
#include <regex>
int main(void)
{
std::cmatch cm;
std::regex_match("subject", cm, std::regex("(sub)(.*)"));
//std::for_each(cm.begin(), cm.end(), [](const std::sub_match<const char *> &s){ <---- Working statement
std::for_each(cm.begin(), cm.end(), [](const std::cmatch &s){ /*<--- Non-working statement*/
std::cout << "match:" << s.str() <<std::endl;
});
return 0;
}
The error is as following:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/algorithm:853:9: error: no matching function for call to object of type '(lambda at main.cpp:73:41)'
__f(*__first);
^~~
main.cpp:73:10: note: in instantiation of function template specialization 'std::__1::for_each<std::__1::__wrap_iter<const std::__1::sub_match<const char *> *>, (lambda at main.cpp:73:41)>' requested here
std::for_each(cm.begin(), cm.end(), [](const std::match_results<const char*> &s){
^
main.cpp:73:41: note: candidate function not viable: no known conversion from 'const std::__1::sub_match<const char *>' to 'const std::match_results<const char *>' for 1st argument
std::for_each(cm.begin(), cm.end(), [](const std::match_results<const char*> &s){
^
maintool.cpp:73:41: note: conversion candidate of type 'void (*)(const std::match_results<const char *> &)'
1 error generated.
In non-working example why is template deduced as std::__1::for_each<std::__1::__wrap_iter<const std::__1::sub_match<const char *> *> ?
I was expecting param will be deduced to be std:::cmatch
Can you please explain how param deduction is working here?
std::cmatch is an alias for std::match_results<char const*>; you want std::sub_match<char const*>, whose alias is std::csub_match.
std::for_each(cm.begin(), cm.end(), [](const std::csub_match &s) { ... }
The following code fails to compile for me (gcc 4.6.3, Ubuntu 12.04):
#include <inttypes.h>
#include <stdio.h>
static inline void adjustBuffer(const uint8_t *&buf, size_t &bufSize, size_t len)
{
buf += len;
bufSize -= len;
}
uint16_t packInt(uint8_t *&buf, size_t &bufSize, int value)
{
size_t valueSize = sizeof(int);
*reinterpret_cast<int *>(buf) = value;
adjustBuffer(buf, bufSize, valueSize);
return valueSize;
}
bool unpackInt(const uint8_t *&buf, size_t &bufSize, int &value)
{
value = *reinterpret_cast<const int*>(buf);
adjustBuffer(sizeof(int));
return true;
}
int main()
{
static const size_t BufSize = 100;
size_t bufSize = BufSize;
uint8_t buf[BufSize];
uint8_t *buf_ptr = buf;
packInt(buf_ptr, bufSize, 1);
bufSize = BufSize;
int x;
unpackInt(buf, bufSize, x);
return 0;
}
I get the following errors:
$ make CXXFLAGS="-Wall -g" ref_to_ptr
g++ -Wall -g ref_to_ptr.cpp -o ref_to_ptr
ref_to_ptr.cpp: In function ‘uint16_t packInt(uint8_t*&, size_t&, int)’:
ref_to_ptr.cpp:15:41: error: invalid initialization of reference of type ‘const uint8_t*& {aka const unsigned char*&}’ from expression of type ‘uint8_t* {aka unsigned char*}’
ref_to_ptr.cpp:5:20: error: in passing argument 1 of ‘void adjustBuffer(const uint8_t*&, size_t&, size_t)’
ref_to_ptr.cpp: In function ‘bool unpackInt(const uint8_t*&, size_t&, int&)’:
ref_to_ptr.cpp:22:29: error: invalid initialization of non-const reference of type ‘const uint8_t*& {aka const unsigned char*&}’ from an rvalue of type ‘unsigned int’
ref_to_ptr.cpp:5:20: error: in passing argument 1 of ‘void adjustBuffer(const uint8_t*&, size_t&, size_t)’
ref_to_ptr.cpp: In function ‘int main()’:
ref_to_ptr.cpp:35:30: error: invalid initialization of non-const reference of type ‘const uint8_t*& {aka const unsigned char*&}’ from an rvalue of type ‘uint8_t* {aka unsigned char*}’
ref_to_ptr.cpp:19:6: error: in passing argument 1 of ‘bool unpackInt(const uint8_t*&, size_t&, int&)’
make: *** [ref_to_ptr] Error 1
It seems the compiler has trouble assigning a reference to uint8_t* (uint8_t *&) to a const uint8_t *& (which IIRC is a reference to pointer to const). First, I don't understand why it tries to assign a pointer to uint8_t and not a reference to a pointer. Second, shouldn't the conversion work? You can convert uint8_t * to const uint8_t *, why wouldn't converting references to both types work?
Of course, adding an adjustBuffer() that takes a const uint8_t *& works, but I'd like to understand why
Passing an uint8_t * as a const uint8_t *& parameter would allow the function to replace the unint8_t * with a const uint8_t *. Now there is a const uint8_t *in the place where the caller expects a modifiable uint8_t *. This is not save, since the caller might modify the pointed-to data after the function returned.
The problem is the same as in this C++ FAQ lite section.