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
// 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
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