I'm using the Crypto++ library, and I created this simple class:
class EncoderRSA
{
public:
EncoderRSA();
void keyGeneration();
void substitutePublicKey(Integer e, Integer n);
Integer encode(std::string plainText);
std::string decode(Integer cypher);
private:
AutoSeededRandomPool prng; // Pseudo Random Number Generator
RSA::PublicKey publicKey; // For encrypt plain text
RSA::PrivateKey privateKey; // For decrypt plain text
};
But I have some problem: when I encoded my message using EncoderRSA::encode(message), I want to convert it from Integer to char* (for send by sockets) and from char* to Integer (after receive on the other side). How can I do it?
Integer to char* and char* to Integer conversion
I'm going to answer the question in the title, and side step the body's question because that appear to encrypt, and not encode.
Integer to char*
Its easy to get a char* because the Integer class (header, implementation) overloads operator<<.
So, you would do something like:
#include <iostream>
#include <sstream>
#include <string>
#include "integer.h"
...
using std::cout;
using std::endl;
using std::string;
using CryptoPP::Integer;
// Perhaps this is received from the EncoderRSA::encode() function
Integer n = ...;
ostringstream oss;
oss << n;
// Create this temporary; otherwise, you might get yourself into trouble
string str(oss.str());
cout << "string: " << str << endl;
cout << "char*: " << str.c_str() << endl;
char* to Integer
This is just as easy because the Integer class has a constructor for it. From integer.h:
// convert from string (requires NULL terminator)
Integer (const char *str)
Here's the program:
#include <string>
#include "integer.h"
...
using std::cout;
using std::endl;
using std::string;
using CryptoPP::Integer;
// Read from the wire
const char data[] = "12345678901234567890123456789012345678901234567890123456789012345678901234567890.";
// Perhaps this is passed to the EncoderRSA::decode() function
Integer n(data, strlen(data));
If you want the byte array version, then...
Integer to byte*
#include <vector>
#include "integer.h"
...
using std::vector;
using CryptoPP::Integer;
// Perhaps this is received from the EncoderRSA::encode() function
Integer n = ...;
size_t sz = n.MinEncodedSize();
vector v;
v.resize(sz);
n.Encode(&v[0], v.size());
byte* to Integer
This is just as easy because the Integer class has a constructor for it. From integer.h:
// convert from string (does NOT require NULL terminator)
Decode (const byte *input, size_t inputLen, Signedness=UNSIGNED)
Here's the program:
#include "integer.h"
...
using CryptoPP::Integer;
// Read from the wire; pretend they are binary
const char byte[] = "12345678901234567890123456789012345678901234567890123456789012345678901234567890";
// Perhaps this is passed to the EncoderRSA::decode() function
Integer n;
n.decode(data, sizeof(data));
You can get even fancier with the encoding and decoding. For example, here's a program that HexEncodes encodes them:
#include <iostream>
#include <string>
#include "integer.h"
...
using std::cout;
using std::endl;
using std::string;
using CryptoPP::Integer;
// Perhaps this is received from the EncoderRSA::encode() function
Integer n("0xfedcba0987654321fedcba0987654321fedcba0987654321fedcba0987654321");
string encoded;
size_t req = n.MinEncodedSize();
encoded.reserve(req);
HexEncoder encoder(new StringSink(encoded));
n.Encode(encoder, req);
cout << encoded << endl;
It produces:
$ ./cryptopp-test.exe
FEDCBA0987654321FEDCBA0987654321FEDCBA0987654321FEDCBA0987654321
And you can switch to a Base64 encoder with:
Base64Encoder encoder(new StringSink(encoded));
n.Encode(encoder, req);
cout << encoded << endl;
It produces:
$ ./cryptopp-test.exe
/ty6CYdlQyH+3LoJh2VDIf7cugmHZUMh/ty6CYdl
Resolve of this problem are next two methods:
Integer EncryptorRSA::stringToInteger(std::string str) {
Integer integer(str.c_str());
return integer;
}
std::string EncryptorRSA::integerToString(Integer integer) {
std::stringstream stream;
stream << std::hex << integer;
return stream.str();
}
Related
I am trying to read a little-endian hex string from a binary file, and put that value into an integer to work with it. When I try to read, instead of getting a number I get ascii symbols. I've tried casts and atoi and nothing seems to work. What is the best way to use fstream to read a hex string into an integer from a file?
This is essentially my program:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(int argc, char* argv[]) {
fstream input;
fstream output;
char cbuffer[4];
char revbuffer[8];
input.open(argv[1], fstream::binary | fstream::in);
output.open("output.txt", ios::out | ios::app);
input.seekg(16, input.beg);
input.read(cbuffer, 4);
cout << sizeof(revbuffer) << endl;
cout << cbuffer[0] << cbuffer[1] << cbuffer[2] << cbuffer[3] << endl;
}
If it's an integer value stored in binary format, I guess it's either a int32_t or a uint32_t. Since you mention that the value is stored in little-endian byte order, I guess you want to make sure that the host running your program converts it (if it needs to). C++20 has std::endian. If that's not available to you, there are usually macros for detecting endianness at compiletime that you can use instead of the std::endian tests I've used. I've assumed that the value is a uint32_t below.
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <type_traits> // std::endian
// little endian unsigned 32 bit integer to host byte order
inline uint32_t Le32toh(uint32_t le) {
#if __cplusplus <= 201703L
// run-time check
static constexpr uint16_t endian = 1;
if(*reinterpret_cast<const uint8_t*>(&endian)==1) return le;
#else
// compile-time check
static_assert(std::endian::native == std::endian::little || std::endian::native == std::endian::big);
if constexpr (std::endian::native == std::endian::little) return le;
#endif
const uint8_t* c=reinterpret_cast<const uint8_t*>(&le);
return // little-to-big endian conversion
(static_cast<uint32_t>(c[0])<<24) |
(static_cast<uint32_t>(c[1])<<16) |
(static_cast<uint32_t>(c[2])<<8) |
(static_cast<uint32_t>(c[3]));
return le;
}
int main(int argc, char* argv[]) {
std::vector<std::string> args(argv+1, argv+argc);
std::fstream output("output.txt", std::ios::out | std::ios::app);
uint32_t cbuffer;
for(const auto& file : args) {
std::fstream input(file, std::fstream::binary | std::fstream::in);
input.seekg(16, input.beg);
// read directly into the varibles memory
input.read(reinterpret_cast<char*>(&cbuffer), 4);
// output the value unconverted
std::cout << std::hex << cbuffer << "\n";
// convert if needed
cbuffer = Le32toh(cbuffer);
// output the value converted
std::cout << std::hex << cbuffer << "\n";
}
}
Here my problem: I want to write a float with max 2 decimal places into a string and print it without a couple of 0's behind the number.
The way I do it at the moment:
Values Material; // Class 'Values', Object 'Material'
Material.Temp = 15.56; // 'Temp' = float
string ss = to_string(Material.Temp); // Conversion to string
const char* cNumber = ss.c_str(); // Conversion to const char
HPDF_Page_ShowText(page, cNumber);
That prints out: 15.56000000
HPDF_Page_ShowText is a command of the open source library libharu to create PDF-Documents. It expects (page-object, *const char). That is the reason why the string has to be converted into a const char* first.
I really searched in the internet for similar problems, but found none that fit to mine.
Use a std::stringstream and std::setprecision() function in combination with the std::fixed stream manipulator:
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
int main(){
float myfloat = 15.56f;
std::stringstream ss;
ss << std::fixed << std::setprecision(2) << myfloat;
std::string s = ss.str();
std::cout << s;
}
The const char* variable can be obtained via:
const char* c = s.c_str();
Update:
Prefer std::ostringstream since the stream is used only for the output.
I'm loosing my mind at the moment and below is what I'm trying to do.
char* buffer;
sprintf(buffer, "0x%08x", 5);
*(int *)(0x834AF2AC + 0x1a) = ?buffer?;
Buffer = 0x05000000
I need to set that in memory, if I just set 05 it will set 0x00000005
Question asked better.
How can I convert an INT into a format of "0x%08x"
So 5 becomes 0x05000000
ANSWERD:
The correct answer is *(int *)(0x834AF2AC + 0x1a) = 5<<24;
Something like this:
#include <iostream> // for std::cout, std::endl
#include <string> // for std::string, std::stoi
int main()
{
std::string s{"0x05"};
int i = std::stoi(s, nullptr, 16); // convert base 16 number in s to int
std::cout << i << std::endl;
}
Two result from google which points to stackoverflow (result 1 and 2).
Convert char to int in C and C++
C char* to int conversion
I'm not sure if I understand correctly but if you want to convert an entire string to int, then I would suggest stringstream.
http://www.cplusplus.com/reference/sstream/stringstream/stringstream/
For hexadecimal string:
#include <string> // std::string
#include <iostream> // std::cout
#include <sstream> // std::stringstream
int main () {
std::stringstream ss;
ss << std::hex << 0x05;
int foo;
ss >> foo;
std::cout << "foo: " << foo << '\n';
return 0;
}
I have the following:
char const* code = "3D";
I need to convert this 2-digit lexical hex into a std::string, which will be a string with length of 1 (not including null terminator). I have the boost library at my disposal as well. How can I do this?
In the example above, I should have a std::string that prints "=" if properly converted.
I think something on this order should work:
std::istringstream buffer("3D");
int x;
buffer >> std::hex >> x;
std::string result(1, (char)x);
std::cout << result; // should print "="
For example, using only standard C++03:
#include <cstdlib>
#include <string>
#include <iostream>
int main() {
char const* code = "3D";
std::string str(1, static_cast<char>(std::strtoul(code, 0, 16)));
std::cout << str << std::endl;
}
In a real application, you'd have to test whether the entire string has been converted (second argument to strtoul) and whether the conversion result is in the allowed range.
Here is a more elaborate example, using C++11 and Boost:
#include <string>
#include <cstddef>
#include <iostream>
#include <stdexcept>
#include <boost/numeric/conversion/cast.hpp>
template<typename T>
T parse_int(const std::string& str, int base) {
std::size_t index = 0;
unsigned long result = std::stoul(str, &index, base);
if (index != str.length()) throw std::invalid_argument("Invalid argument");
return boost::numeric_cast<T>(result);
}
int main() {
char const* code = "3D";
std::string str(1, parse_int<char>(code, 16));
std::cout << str << std::endl;
}
In Boost release 1.50 (coming this May), you would simply write
string s;
boost::algorithm::unhex ( code, std::back_inserter (s));
Works on std::string, std::wstring, QtString, CString, etc, etc.
It's not C++ but you can still use the good old scanf:
int d;
scanf("%x", &d);
Or from a string using sscanf:
int d;
sscanf(code, "%x", &d);
And using a std::string:
int d;
sscanf(code.c_str(), "%x", &d);
For some case the C format function (scanf & printf families) are easier to use than the object-oriented equivalent.
How can i convert an integer ranging from 0 to 255 to a string with exactly two chars, containg the hexadecimal representation of the number?
Example
input: 180
output: "B4"
My goal is to set the grayscale color in Graphicsmagick. So, taking the same example i want the following final output:
"#B4B4B4"
so that i can use it for assigning the color: Color("#B4B4B4");
Should be easy, right?
You don't need to. This is an easier way:
ColorRGB(red/255., green/255., blue/255.)
You can use the native formatting features of the IOStreams part of the C++ Standard Library, like this:
#include <string>
#include <sstream>
#include <iostream>
#include <ios>
#include <iomanip>
std::string getHexCode(unsigned char c) {
// Not necessarily the most efficient approach,
// creating a new stringstream each time.
// It'll do, though.
std::stringstream ss;
// Set stream modes
ss << std::uppercase << std::setw(2) << std::setfill('0') << std::hex;
// Stream in the character's ASCII code
// (using `+` for promotion to `int`)
ss << +c;
// Return resultant string content
return ss.str();
}
int main() {
// Output: "B4, 04"
std::cout << getHexCode(180) << ", " << getHexCode(4);
}
Live example.
Using printf using the %x format specifier. Alternatively, strtol specifying the base as 16.
#include<cstdio>
int main()
{
int a = 180;
printf("%x\n", a);
return 0;
}