Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a standard way of representing an SHA1 hash as a C string, and how do I convert to it?

Tags:

c++

c

openssl

hash

This question is about how to create an SHA-1 hash from an array of data in C using the OpenSSL library.

It returns an array of 20 bytes, containing the hash. Is there some standard way of representing that data in string form, not binary?

If so, is there a function in OpenSSL itself to convert to said string format?

If not, how should it be done? Of course, I can dream up my own encoding, use base64 or what not, but is there some canonical format?

like image 346
Prof. Falken Avatar asked Oct 19 '10 13:10

Prof. Falken


2 Answers

Usually hashes are represented as a sequence of hexadecimal digits (naturally, two per byte). You can write the code to write such thing easily using an ostringstream with the right modifiers:

#include <string>
#include <sstream>
#include <iomanip>

std::string GetHexRepresentation(const unsigned char *Bytes, size_t Length) {
    std::ostringstream os;
    os.fill('0');
    os<<std::hex;
    for(const unsigned char *ptr = Bytes; ptr < Bytes+Length; ++ptr) {
        os<<std::setw(2)<<(unsigned int)*ptr;
    }
    return os.str();
}

Arguably, this can also be done more efficiently (and, to my today's eyes, more clearly) "by hand":

#include <string>

std::string GetHexRepresentation(const unsigned char *Bytes, size_t Length) {
    std::string ret(Length*2, '\0');
    const char *digits = "0123456789abcdef";
    for(size_t i = 0; i < Length; ++i) {
        ret[i*2]   = digits[(Bytes[i]>>4) & 0xf];
        ret[i*2+1] = digits[ Bytes[i]     & 0xf];
    }
    return ret;
}

or with good old sprintf, probably the easiest-to-read method of all:

#include <stdio.h>
#include <string>

std::string GetHexRepresentation(const unsigned char *Bytes, size_t Length) {
    std::string ret;
    ret.reserve(Length * 2);
    for(const unsigned char *ptr = Bytes; ptr < Bytes+Length; ++ptr) {
        char buf[3];
        sprintf(buf, "%02x", (*ptr)&0xff);
        ret += buf;
    }
    return ret;
}
like image 132
Matteo Italia Avatar answered Nov 15 '22 01:11

Matteo Italia


The standard way of representing hashes is as hexadecimal strings.
In C, you can use printf("%02x", byte) to get a hex representation of each byte.

An example for MD5, should be easy to adapt it for SHA:

http://en.literateprograms.org/MD5_sum_(C,_OpenSSL)

like image 33
Arc Avatar answered Nov 15 '22 00:11

Arc