pmnz
pmnz

Reputation: 43

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

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

Upvotes: 2

Views: 9205

Answers (3)

O&#39;Neil
O&#39;Neil

Reputation: 3849

#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();

Upvotes: 6

Stephan Lechner
Stephan Lechner

Reputation: 35154

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

Upvotes: 1

Ben Voigt
Ben Voigt

Reputation: 283733

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).

Upvotes: 0

Related Questions