convert array of long long into string - c++

In c++
I have an array of signed long long (63bit numbers), array of variable lenght.
std::array<long long, n> encodedString
This array is in fact holding an UTF-8 encoded string. Meaning that if you concatenate the binaries of each element of the array, the result will be an UTF-8 encoded text.
For example the array :
(621878499550 , 2339461068677718049)
If you translate those signed long long in 63 bit binary it gives :
621878499550 = 000000000000000000000001001000011001010110110001101100011011110
2339461068677718049 = 010000001110111011011110111001001101100011001000010000000100001
If you concatenate those binaries into :
000000000000000000000001001000011001010110110001101100011011110010000001110111011011110111001001101100011001000010000000100001
This is the UTF8 for "Hello world !"
So the question is what is the easiest way to get a string with "Hello world !" starting with the array (621878499550 , 2339461068677718049)
Best solution I currently have is to write the array to a file in binary mode (fwrite) then read the file in text mode to a string.

Use bitset to convert a long long to binary and string stream to stream them
#include <sstream>
#include <iostream>
#include <bitset>
#include <array>
int main()
{
std::array<long long, 2> array = { 621878499550 , 2339461068677718049ll };
std::stringstream ss;
for (auto& n : array)
{
ss << std::bitset<64>(n);
}
std::cout << ss.str() << std::endl;
}
which outputs 0000000000000000000000010010000110010101101100011011000110111100010000001110111011011110111001001101100011001000010000000100001

Try this
// 48 & 56 were to avoid the extra padding made when you use 64 bitset but i think thats what you are looking for
std::string binary = std::bitset<48>(114784820031264).to_string();
std::string binary2 = std::bitset<56>(2339461068677718049).to_string();
binary += binary2;
std::stringstream sstream(binary);
std::string output;
while (sstream.good())
{
std::bitset<8> bits;
sstream >> bits;
output +=char(bits.to_ulong());
}
std::cout << output;

Related

Convert string in '\\x00\\x00\\x00' format to unsigned char array

Say I have a string as so:
std::string sc = "\\xfc\\xe8\\x82";
how could I convert the sc string into the equivalent of
unsigned char buf[] = "\xfc\xe8\x82";
I'm trying to convert a string containing shellcode into a unsigned char array.
I have tried the following:
char buf[5120];
strncpy(buf, sc.c_str(), sizeof(buf));
buf[sizeof(buf) - 1] = 0;
This seems to store strings into the char array I need the char array to store/represent bytes.
When I print:
//example 1
unsigned char buf[] = "\xfc\xe8\x82";
printf("%s", buf);
The console outputs:
ⁿΦé
When I print:
//example 2
char buf[5120];
strncpy(buf, sc.c_str(), sizeof(buf));
buf[sizeof(buf) - 1] = 0;
The Console outputs:
\xfc\xe8\x82
How do I convert the sc string into a unsigned char array so that when sc is printed sc will produce the same output of example 1.
The literal "\\xfc\\xe8\\x82" as a string uses "\" as an escape character. "\\" will be reduced to "\". As you would expect. So, if you print your given std::string, then the result will be:
\xfc\xe8\x82.
So, what you want to do now is: Create a char array containing those hex values, given in the original std::string.
Please note: Your statement char s[] = "\xfc\xe8\x82"; will create a C-Style array of char, with the size 4 and containing:
s[0]=fc, s[1]=e8, s[2]=82, s[3]=0
In the example below I show 2 proposals for conversion.
1. Straight forward conversion
2. Using C++ standard algorithms
#include <string>
#include <iostream>
#include <iomanip>
#include <regex>
#include <vector>
#include <iterator>
#include <algorithm>
// Hex digit String
std::regex hexValue{R"(\\[xX]([0-9a-fA-F][0-9a-fA-F]))"};
int main ()
{
// Source string
std::string s1 = "\\xfc\\xe8\\x82";
std::cout << "s 1: " << s1 << "\n";
// Proposal 1 ------------------------------------------------------
// Target array
unsigned char s2[3];
// Convert bytes from strings
for (int i=0; i<s1.size()/4; ++i ) {
// Do conversion. Isolate substring, the convert
s2[i] = std::strtoul(s1.substr(i*4+2,2).c_str(), nullptr,16);
// Result is now in s2
// Output value as tring and decimal value
std::cout << s1.substr(i*4+2,2) << " -> " << std::hex << static_cast <unsigned short>(s2[i])
<< " -> " << std::dec << static_cast <unsigned short>(s2[i]) << "\n";
}
// Proposal 2 ------------------------------------------------------
// Get the tokens
std::vector<std::string> vstr(std::sregex_token_iterator(s1.begin(),s1.end(),hexValue, 1), {});
// Convert to unsigned int
std::vector<unsigned int> vals{};
std::transform(vstr.begin(), vstr.end(), std::back_inserter(vals),
[](std::string &s){ return static_cast<unsigned>(std::strtoul(s.c_str(), nullptr,16)); } );
// Print output on std::cout
std::copy(vals.begin(), vals.end(), std::ostream_iterator<unsigned>(std::cout,"\n"));
return 0;
}
The second solution will eat any number of hex numbers given in a string

How to convert a hexadecimal string to long in c++

I have a string which is as shown below.
std::string myString = "0005105C9A84BE03";
I want the exact data to be saved on some integer say "long long int"
long long int myVar = 0005105C9A84BE03;
When i print myVar i'm expecting output 1425364798979587.
I tried to use atoi, strtol stroi, strtoll but nothing worked out for me.
Any idea how to solve it?
The following should work:
#include <iostream>
#include <sstream>
int main()
{
std::string hexValue = "0005105C9A84BE03"; // Original string
std::istringstream converter { hexValue }; // Or ( ) for Pre-C++11
long long int value = 0; // Variable to hold the new value
converter >> std::hex >> value; // Extract the hex value
std::cout << value << "\n";
}
This code uses an std::istringstream to convert from std::string to long long int, through the usage of the std::hex stream manipulator.
Example
There is a list of functions to convert from string to different integer types like:
stol Convert string to long int (function template )
stoul Convert string to unsigned integer (function template )
strtol Convert string to long integer (function )
They are some more. Please take a look at http://www.cplusplus.com/reference/string/stoul At the end of the documentation you find alternative functions for different data types.
All they have a "base" parameter. To convert from hex simply set base=16.
std::cout << std::stoul ("0005105C9A84BE03", 0, 16) << std::endl;

std::string stream parse a number in binary format

I need to parse an std::string containing a number in binary format, such as:
0b01101101
I know that I can use the std::hex format specifier to parse numbers in the hexadecimal format.
std::string number = "0xff";
number.erase(0, 2);
std::stringstream sstream(number);
sstream << std::hex;
int n;
sstream >> n;
Is there something equivalent for the binary format?
You can use std::bitset string constructor and convert bistet to number:
std::string number = "0b101";
//We need to start reading from index 2 to skip 0b
//Or we can erase that substring beforehand
int n = std::bitset<32>(number, 2).to_ulong();
//Be careful with potential overflow
You can try to use std::bitset
for example:
skip two first bytes 0b
#include <bitset>
...
std::string s = "0b0111";
std::bitset<4>x(s,2); //pass string s to parsing, skip first two signs
std::cout << x;
char a = -20;
std::bitset<8> x(a);
std::cout << x;
short b = -427;
std::bitset<16> y(c);
std::cout << y;

Writing hex to a file

I have a program that reads the hex of a file, modifies it, and stores the modified hex in a std::string.
For example, how would I write this to a file
std::string wut="b6306edf953a6ac8d17d70bda3e93f2a3816eac333d1ac78";
and get its value
.0n..:j..}p...?*8...3..x
in the outputted file?
I'd prefer not to use sprintf, but I guess if it's necessary, I'll do what I must.
If I understand your question correctly you want the text converted to it's numeric equivalent and then written to file. Given the hint you provided in your question it looks like this should be done byte by byte. Below is one way to achieve this. Note the need to convert each byte from a string to an integer value.
#include <string>
#include <sstream>
#include <iostream>
#include <fstream>
#include <ios>
std::string wut = "b6306edf953a6ac8d17d70bda3e93f2a3816eac333d1ac78";
int main()
{
std::ofstream datafile("c:\\temp\\temp1.dat", std::ios_base::binary | std::ios_base::out);
char buf[3];
buf[2] = 0;
std::stringstream input(wut);
input.flags(std::ios_base::hex);
while (input)
{
input >> buf[0] >> buf[1];
long val = strtol(buf, nullptr, 16);
datafile << static_cast<unsigned char>(val & 0xff);
}
}
The answer of #Peter R will lead to an output which is not 100% equal, due to the stringstream interpreting more than one '0's in a row in an unintended way.
Example: If we want to write the hex value "00000000", the stringstream would output " 000000".
The solution below works in every case, no matter how many zeros are contained in the hex string:
// Input
std::string hex = "180f00005e2c3415"; // (or longer)
std::basic_string<uint8_t> bytes;
// Iterate over every pair of hex values in the input string (e.g. "18", "0f", ...)
for (size_t i = 0; i < hex.length(); i += 2)
{
uint16_t byte;
// Get current pair and store in nextbyte
std::string nextbyte = hex.substr(i, 2);
// Put the pair into an istringstream and stream it through std::hex for
// conversion into an integer value.
// This will calculate the byte value of your string-represented hex value.
std::istringstream(nextbyte) >> std::hex >> byte;
// As the stream above does not work with uint8 directly,
// we have to cast it now.
// As every pair can have a maximum value of "ff",
// which is "11111111" (8 bits), we will not lose any information during this cast.
// This line adds the current byte value to our final byte "array".
bytes.push_back(static_cast<uint8_t>(byte));
}
// we are now generating a string obj from our bytes-"array"
// this string object contains the non-human-readable binary byte values
// therefore, simply reading it would yield a String like ".0n..:j..}p...?*8...3..x"
// however, this is very useful to output it directly into a binary file like shown below
std::string result(begin(bytes), end(bytes));
Then you can simply write this string to a file like this:
std::ofstream output_file("filename", std::ios::binary | std::ios::out);
if (output_file.is_open())
{
output_file << result;
output_file.close();
}
else
{
std::cout << "Error could not create file." << std::endl;
}

how to convert a hexadecimal string to a corresponding integer in c++?

i have a unicode mapping stored in a file.
like this line below with tab delimited.
a 0B85 0 0B85
second column is a unicode character. i want to convert that to 0x0B85 which is to be stored in int variable.
how to do it?
You've asked for C++, so here is the canonical C++ solution using streams:
#include <iostream>
int main()
{
int p;
std::cin >> std::hex >> p;
std::cout << "Got " << p << std::endl;
return 0;
}
You can substitute std::cin for a string-stream if that's required in your case.
You could use strtol, which can parse numbers into longs, which you can then assign to your int. strtol can parse numbers with any radix from 2 to 36 (i.e. any radix that can be represented with alphanumeric charaters).
For example:
#include <cstdlib>
using namespace std;
char *token;
...
// assign data from your file to token
...
char *err; // points to location of error, or final '\0' if no error.
int x = strtol(token, &err, 16); // convert hex string to int