Septagram
Septagram

Reputation: 9785

How to hash std::string?

I'm making a little utility to help me remember passwords by repetition. I'd like to enter password to be remembered only once every day and not before each session. Of course, I wouldn't store a password itself, but would gladly store its hash.

So, what are the easiest ways to get a hash from std::string using the C++ Standard Library?

Upvotes: 33

Views: 111447

Answers (5)

Neel Basu
Neel Basu

Reputation: 12904

That algorithm used in std::hash is implementation dependent. The guarantees it provide is not sufficient if you intend to store the hash values in the database for long term usage. Following is quoted from cppreference.

The actual hash functions are implementation-dependent and are not required to fulfill any other quality criteria except those specified above. Notably, some implementations use trivial (identity) hash functions which map an integer to itself. In other words, these hash functions are designed to work with unordered associative containers, but not as cryptographic hashes, for example.

Hash functions are only required to produce the same result for the same input within a single execution of a program; this allows salted hashes that prevent collision denial-of-service attacks.

However for std::basic_string it may be somewhat more stable than other multibyte numeric types.

The best solution is use Cryptographic Hash Functions (CHF) such as md5 (unsafe), sha512, etc..

However, it may be computationally expensive to compute CHF if you are hashing too many long strings frequently or you don't need the security assumptions provided by the CHFS. Non Cryptographic Hash functions such as crc32, murmur, fnv1a etc.. may be a better fit for such requirements. However, the problem with these functions are collisions. I've encountered similar situation in past. So, I mixed multiple non-cryptographic hash functions to reduce collision.

The library is available at github. But, I didn't have time for measuring its collision resistance. I used mixed hash and it worked for my problem.

Hashes can be computed using the hash_value function as shown below.

noch::hash_value<noch::algorithms::mixed1>(std::string("Hello")).

Upvotes: 0

vSzemkel
vSzemkel

Reputation: 692

First some theory: https://cp-algorithms.com/string/string-hashing.html
For serious problems use pair of hashes with different bases.
In linear time one can build hasher to answer hash query of ANY substring of a given string in N(1)
Simple working example from my github: https://github.com/vSzemkel/CppStuff/blob/master/classic/polynomial_hasher.cpp

Upvotes: 1

Kashyap
Kashyap

Reputation: 17441

You can use the STL functor hash. See if your STL lib has it or not.

Note that this one returns a size_t, so range is numeric_limits<size_t>::min() numeric_limits<size_t>::max(). You'll have to use SHA or something if that's not acceptable..

Upvotes: 3

Ou Wei
Ou Wei

Reputation: 421

using c++11, you can:

#include <string>
#include <unordered_map>

std::size_t h1 = std::hash<std::string>{}("MyString");
std::size_t h2 = std::hash<double>{}(3.14159);

see more here.

Upvotes: 42

Seth Carnegie
Seth Carnegie

Reputation: 75130

For a quick solution involving no external libraries, you can use hash<std::string> to hash strings. It's defined by including the header files hash_map or unordered_map (or some others too).

#include <string>
#include <unordered_map>

hash<string> hasher;

string s = "heyho";

size_t hash = hasher(s);

If you decide you want the added security of SHA, you don't have to download the large Crypto++ library if you don't need all its other features; there are plenty of standalone implementations on the internet, just search for "sha implementation c++".

Upvotes: 45

Related Questions