|
Boost Users : |
From: Bill Lear (rael_at_[hidden])
Date: 2007-11-07 21:10:56
On Wednesday, November 7, 2007 at 23:45:13 (+0000) Daniel James writes:
>Mark Wyszomierski wrote:
>> Hi,
>>
>> I'm trying to hash a string, something like:
>>
>> 1) Take string (password) from user
>> 2) Hash it
>> 3) Store to disk
>>
>> I see boost has some hashing features, but am not quite sure how they
>> work. Do they do this type of thing? I'm looking for some really
>> simple hashing, this is just for a simple application.
>
>No, they're not suitable. Boost.Hash is designed to be used with in
>memory hash tables.
>
>You probably need a cryptographic hash, such as MD5 or one of the SHA
>hash functions. I think the Adobe Source Libraries include these. And
>there has also been talk of implementations for boost in the past (check
>the vault and/or archives) but I don't think anything has been put
>forward for review.
This might be of use... may need some rejiggering.
// .hh file
#include <vector>
#include <string>
#include <iosfwd>
#include <openssl/evp.h>
// Generates a SHA1 checksum for the given stream
std::vector<unsigned char> sha1sum(std::istream&);
// Generates a SHA1 checksum for the given file
std::vector<unsigned char> sha1sum(const std::string&);
// converts the sha1sum vector to a hexadecimal string
std::string sha1_to_string(const std::vector<unsigned char>&);
//---------------------------------------------------------------------------//
// Provides, inter alia, semantics to support intermediate calculation of
// sha1 checksums. This is useful, for example, in graph traversal, during
// which you may want to know the sha1 sum of the current path. The
// underlying implementation does not allow "un-digesting" of content,
// so testing to see if a current node in a path creates a sha1 that
// has been seen before *without modifying the current path's sha1*
// requires a copy of the Sum object to a temporary object,
// the addition of the node, and test to see if the new sha1 has been
// seen.
//---------------------------------------------------------------------------//
class Sum {
public:
Sum();
~Sum();
Sum(const Sum&);
Sum& operator = (const Sum&);
// Add new content
void digest(const char*, size_t);
void digest(const std::string&);
// Get sha1 value; digest() may be called again
std::string sha1();
private:
const EVP_MD* md;
EVP_MD_CTX mdctx;
};
// .cc file
#include <fstream>
#include <stdio.h>
using namespace std;
vector<unsigned char> sha1sum(istream& is) {
const EVP_MD* md = EVP_sha1();
Insist(md, "Unable to get sha1 message digest structure");
OpenSSL_add_all_digests();
EVP_MD_CTX mdctx;
EVP_MD_CTX_init(&mdctx);
EVP_DigestInit_ex(&mdctx, md, NULL);
const size_t buffer_length = 1024 * 1024;
static char buffer[buffer_length];
while (true) {
is.read(buffer, buffer_length);
if (!is.gcount()) {
break;
}
EVP_DigestUpdate(&mdctx, buffer,
static_cast<unsigned int>(is.gcount()));
}
unsigned char md_value[EVP_MAX_MD_SIZE];
unsigned int md_len = 0;
EVP_DigestFinal_ex(&mdctx, md_value, &md_len);
EVP_MD_CTX_cleanup(&mdctx);
return vector<unsigned char>(md_value, md_value + md_len);
}
vector<unsigned char> sha1sum(const string& filename) {
ifstream is(filename.c_str());
Insist(is.good(), "Unable to open " + filename + " for reading." );
return sha1sum(is);
}
string sha1_to_string(const vector<unsigned char>& v) {
string sha1;
for (vector<unsigned char>::const_iterator i = v.begin(); i != v.end(); ++i)
{
char b[8];
sprintf(b, "%02x", *i);
sha1 += b;
}
return sha1;
}
Sum::Sum() : md(EVP_sha1()) {
Insist(md, "Unable to get sha1 message digest structure");
OpenSSL_add_all_digests();
EVP_MD_CTX_init(&mdctx);
EVP_DigestInit_ex(&mdctx, md, NULL);
}
Sum::~Sum() {
EVP_MD_CTX_cleanup(&mdctx);
}
Sum::Sum(const Sum& other) : md(EVP_sha1()) {
Insist(md, "Unable to get sha1 message digest structure");
OpenSSL_add_all_digests();
EVP_MD_CTX_init(&mdctx);
EVP_DigestInit_ex(&mdctx, md, NULL);
EVP_MD_CTX_copy_ex(&mdctx, &other.mdctx);
}
Sum& Sum::operator = (const Sum& other) {
if (this != &other) {
EVP_MD_CTX_copy_ex(&mdctx, &other.mdctx);
}
return *this;
}
void Sum::digest(const char* buffer, size_t length) {
EVP_DigestUpdate(&mdctx, buffer, static_cast<unsigned int>(length));
}
void Sum::digest(const string& buffer) {
EVP_DigestUpdate(&mdctx, buffer.c_str(),
static_cast<unsigned int>(buffer.size()));
}
string Sum::sha1() {
EVP_MD_CTX mdctx_tmp;
EVP_MD_CTX_copy(&mdctx_tmp, &mdctx);
unsigned char md_value[EVP_MAX_MD_SIZE];
unsigned int md_len = 0;
EVP_DigestFinal_ex(&mdctx_tmp, md_value, &md_len);
EVP_MD_CTX_cleanup(&mdctx_tmp);
vector<unsigned char> v(md_value, md_value + md_len);
return sha1_to_string(v);
}
Bill
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net