2

While learning some basics with OpenSSL I came across code to create an SHA256 hash:

using namespace std;

    #include <openssl/sha.h>
    string sha256(const string str)
    {
        unsigned char hash[SHA256_DIGEST_LENGTH];
        SHA256_CTX sha256;
        SHA256_Init(&sha256);
        SHA256_Update(&sha256, str.c_str(), str.size());
        SHA256_Final(hash, &sha256);
        stringstream ss;
        for(int i = 0; i < SHA256_DIGEST_LENGTH; i++)
        {
            ss << hex << setw(2) << setfill('0') << (int)hash[i];
        }
        return ss.str();
    }

Can someone please explain what ss << hex << setw(2) << setfill('0') << (int)hash[i]; does in this specific example as simply as possible, while still explaining it efficiently?

As I can't seem to make sense of these answers, they aren't helping with understanding my specific snippet:

Community
  • 1
  • 1
Semaphore
  • 63
  • 1
  • 12
  • Do you know what each of the [manipulators](http://en.cppreference.com/w/cpp/io/manip) do on their own? Have you tried experimenting with them while printing to `std::cout`? – Some programmer dude Dec 18 '16 at 06:16
  • Then you should probably [find a good beginners book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) as it should explain these *manipulators* and what they do. You could also do the output to `cout` instead of `ss` and see what you get. And most importantly, experiment! :) – Some programmer dude Dec 18 '16 at 06:22
  • 1
    @Someprogrammerdude I do not, I hardly know anything on std:: anything as I am just switching to c++ from C, and I'm having a hard time learning everything at once and making sense of docs – Semaphore Dec 18 '16 at 06:22

1 Answers1

4

In C++ there are many different streams. You probably know about cout to write output to the console, and cin to read input. stringstream is a class whose object write to and read from string objects. Writing to a string stream (like the variable ss) is just like writing to cout, but writes to a string instead of the console.

You say you have programmed C? Then you should know about hexadecimal notation, right? That is what the hex manipulator tells the stream to use. This is similar to the printf format specifier "%x".

The setw manipulator sets the field width of the next output.

The setfill manipulator sets the fill character of the output.

Finally the casting of hash[i] to int is because hash[i] is a char and output to a stream will write it as a character and not a small integer.

In short,

ss << hex << setw(2) << setfill('0') << (int)hash[i];

is equivalent to the C code

sprintf(temporaryBuffer, "%02x", hash[i]);
strcat(ss, temporaryBuffer);
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621