C++ how to convert unsigned char array to string? - c++

I'm testing a piece of code that performs a hash operation (sha256) of a binary file and I've got something like this:
for(i = 0; i < SHA256_DIGEST_LENGTH; i++) printf("%02x", c[i]);
This prints something like:
12b64492d18aa37d609f27cb02ce5ba381068d1ef5625193df68451c650a2b8d
I'm asking how can I do to get the string shown below into a string variable in C++.
thanks

#include <iomanip>
#include <sstream>
#include <string>
std::ostringstream oss;
for(int i = 0; i < SHA256_DIGEST_LENGTH; ++i)
{
oss << std::hex << std::setw(2) << std::setfill('0') << +c[i];
}
auto str = oss.str();

For printing out hex values, you can use std::hex format; for setting width and fill character, use std::setw and std::setfill, which are part of <iomanip>.
As you do not show the data type of c, I suppose/suggest to use an unsigned integral type, e.g. unsigned char. I slightly adapted the code to make it self contained):
#define SHA256_DIGEST_LENGTH 256
#include <iostream>
#include <sstream>
#include <iomanip>
int main() {
unsigned char c[SHA256_DIGEST_LENGTH];
for (unsigned int i=0; i<SHA256_DIGEST_LENGTH; i++)
c[i]=i;
std::stringstream ss;
for(int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
ss << std::hex << std::setw(2) << std::setfill('0') << (unsigned int)c[i];
}
std::cout << ss.str();
}
Output:
000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff

Just for comparison, here's the sprintf version:
#include <stdio.h>
#include <string>
std::string ss;
ss.resize(SHA256_DIGEST_LENGTH * 2 + 1); // includes space for terminating NUL
int used = 0;
for(int i = 0; i < SHA256_DIGEST_LENGTH; i++)
used += sprintf(&ss[used], "%02x", c[i]);
ss.resize(used);
Note that there's no harm in making the buffer larger than necessary initially because the final exact size is used, but if there's any possibility the buffer is too small then one must use snprintf and also pass the buffer space remaining (ss.size() - used).

Related

I want to store the following line into a string array in C++. How can I do it?

I want to make a string array in C++ which holds 0000, 0001, 00002, 0003 and so on up to 9999. Is there any way to implement this with loop. I do not want to take input manually. I want something like this.
for(i=0;i<10000;i++)
str[i] = i;
https://ideone.com/4kayTz
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <iomanip>
int main() {
std::vector<std::string> str(10000);
std::stringstream ss;
ss << std::setfill('0');
for (int i = 0; i < 10000; i++) {
ss << std::setw(4) << i;
str[i] = ss.str();
ss.str(""); // Reset/make empty the string stream.
std::cout << str[i] << std::endl;
}
return 0;
}

std::hex and std::setw not working with some characters

What I'm trying to do is converting a string's bytes into hexadecimal format.
Based on this answer (and many others consistent) I've tried the code:
#include <sstream>
#include <iomanip>
#include <iostream>
int main ()
{
std::string inputText = u8"A7°";
std::stringstream ss;
// print every char of the string as hex on 2 values
for (unsigned int i = 0; i < inputText.size (); ++i)
{
ss << std::hex << std::setfill ('0') << std::setw (2) << (int) inputText[i];
}
std::cout << ss.str() << std::endl;
}
but with some characters coded in UTF 8 it does't work.
For Instance, in strings containing the degrees symbol ( ° ) coded in UTF8, the result is: ffffffc2ffffffb0 instead of c2b0.
Now I would expect the algorithm to work on individual bytes regardless of their contents and furthermore the result seems to ignore the setw(2) parameter.
Why does I get such a result?
(run test program here)
As Pete Becker already hinted in a comment, converting a negative value to a larger integer fills the higher bits with '1'. The solution is to first cast the char to unsigned char before casting it to int:
#include <string>
#include <iostream>
#include <iomanip>
int main()
{
std::string inputText = "-12°C";
// print every char of the string as hex on 2 values
for (unsigned int i = 0; i < inputText.size(); ++i)
{
std::cout << std::hex << std::setfill('0')
<< std::setw(2) << (int)(unsigned char)inputText[i];
}
}
setw sets the minimal width, it does not truncate longer values.

C++ Looping with String Functions

I'm doodling with this implementation of SHA-256. I'm trying to write a program that produces sha(0), sha(1), ... but I'm unable to. Naively I tried
#include <iostream>
#include "sha256.h"
int main(int argc, char *argv[]){
for (int i=0; i < 4; i++)
std::cout << sha256("i");
return 0;
}
Of course, this doesn't produce sha256(0), sha256(1), ..., but rather interprets the i as the letter i, and not the integer variable i. Any advice on how to remedy this? Altering the function implentation itself is not feasible so I'm looking for another way. Clearly I don't know much C++ at all, but any advice would be much appreciated.
EDIT:
#include <iostream>
#include "sha256.h"
#include <sstream>
int main(int argc, char *argv[])
{
std::cout << "This is sha256("0"): \n" << sha256("0") << std::endl;
std::cout << "Loop: " << std::endl;
std::stringstream ss;
std::string result;
for (int i=0; i < 4; ++i)
{
ss << i;
ss >> result;
std::cout << sha256(result) << std::endl;
}
return 0;
You need to transform the number i to the string i accepted by SHA. A straightforward option is to use the std::to_string C++11 function
std::cout << sha256(std::to_string(i));
In case you don't have access to a C++11 compiler (you should have, it's almost 2016), you can glance at this excellent link:
Easiest way to convert int to string in C++
Quick (not the most efficient) way of doing it with a std::stringstream:
#include <iostream>
#include <sstream>
#include "sha256.h"
int main()
{
std::string result;
std::stringstream ss;
for (int i = 0; i < 4; i++)
{
ss << i;
ss >> result;
ss.clear(); // need to clear the eof flag so we can reuse it
std::cout << sha256(result) << std::endl;
}
}

snprintf c++ alternative

How can I convert this code from C into C++ ?
char out[61]; //null terminator
for (i = 0; i < 20; i++) {
snprintf(out+i*3, 4, "%02x ", obuf[i])
}
I can't find any alternative for snprintf.
Use stringstream class from <sstream>.
E.g.:
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
using namespace std;
int main()
{
stringstream ss;
for (int i = 0; i < 20; i++) {
ss << setw(3) << i;
}
cout << "Resulting string: " << endl;
cout << ss.str() << endl;
printf("Resulting char*: \n%s\n", ss.str().c_str() );
return 0;
}
This code is valid C++11, if you have #include <cstdio> and type std::snprintf (or using namespace std;).
No need to "fix" what isn't broken.
You can use Boost.Format.
#include <boost/format.hpp>
#include <string>
std::string out;
for (size_t i=0; i<20; ++i)
out += (boost::format("%02x") % int(obuf[i])).str();
You can convert this code from C to C++ easily with standard library's std::stringstream and iomanip I/O stream manipulators:
#include <sstream>
#include <iomanip>
...
std::ostringstream stream;
stream << std::setfill('0') << std::hex;
for (const auto byte : obuf)
stream << std::setw(2) << byte;
const auto out = stream.str();

How to convert ASCII string to hexadecimal?

I have tried to find this topic on the web but I couldn't find the one I need.
I have a string of character:
char * tempBuf = "qj";
The result I want is 0x716A, and that value is going to be converted into decimal value.
Is there any function in vc++ that can be used for that?
You can use a stringstream to convert each character to a hexadecimal representation.
#include <iostream>
#include <sstream>
#include <cstring>
int main()
{
const char* tempBuf = "qj";
std::stringstream ss;
const char* it = tempBuf;
const char* end = tempBuf + std::strlen(tempBuf);
for (; it != end; ++it)
ss << std::hex << unsigned(*it);
unsigned result;
ss >> result;
std::cout << "Hex value: " << std::hex << result << std::endl;
std::cout << "Decimal value: " << std::dec << result << std::endl;
}
So if I understood correctly the idea...
#include <stdint.h>
uint32_t charToUInt32(const char* src) {
uint32_t ret = 0;
char* dst = (char*)&ret;
for(int i = 0; (i < 4) && (*src); ++i, ++src)
dst[i] = *src;
return ret;
}
If I understand what you want correctly: just loop over the characters, start to finish; at each character, multiply the sum so far by 256, and add the value of the next character; that gives the decimal value in one shot.
What you are looking for is called "hex encoding". There are a lot of libraries out there that can do that (unless what you were looking for was how to implement one yourself).
One example is crypto++.