How to hash std::string?
Asked Answered
R

4

33

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?

Ravin answered 6/11, 2011 at 18:0 Comment(4)
I don't yet get your goal: "help me remember passwords by repetition" - you want a tool which lets you repeat your password often so you remember it more easily? This does not fit to the rest of the question, though.Algorithm
@PaŭloEbermann, that was just for the context. Yes, a tool to practice entering a strong password days before I apply it to anything, so I won't suddenly forget it.Ravin
Beware: There are two common ways to use hashes. The first is the hash in a hash map: it must have a good distribution and be quick to compute (typical: Murmur3, CityHash), it is better if there are few collisions, but it might not matter so much. The second is a cryptographically secure hash, and even then there are various usages (signature vs password storage). For the case of password storage, you'll want something that is expensive to compute, examples include blowfish, and you'll want to salt your password before hashing it (decide the salt at random, store it along the hash).Sale
@Ravin read xkcd.com/936Phonotypy
P
44

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++".

Phonotypy answered 6/11, 2011 at 18:5 Comment(15)
This isn’t a cryptographically secure hash.Ravens
@KonradRudolph but he did say "easiest way" and "using [C++ Standard Library]," so I thought I'd let him know of this because it fits both of those criteria.Phonotypy
It's not important if someone can break the hash for this program as long as original password is not recovered. And it will be of high entropy, hence the need for a program to remember it :) If it's possible to recover original password, please tell me, as I'm not very good at cryptography.Ravin
@Ravin I don't think there is a single standard implementation of hash. So the results you get from using it are going to vary from compiler to compiler. That just means that I don't know if it's reversible or not because the people who write the implementation probably don't put great care into seeing that it's not reversible since they didn't anticipate someone using it to hash passwords (probably).Phonotypy
So it's possible that it's reversible with an entropy of, say, 96 bits?Ravin
I have no idea, sorry, I know less than nothing about cryptography. @KonradRudolph can you answer his question?Phonotypy
@Ravin if you decide you want the added security of SHA, you don't have to download a large library such as Crypto++; you can find standalone SHA implementations easily on google, such as this one: packetizer.com/security/sha1Phonotypy
@Ravin What do you actually want to do with the hash? On this it depends whether a simple hash<...> implementation is suitable or not. (I guess, it isn't.)Algorithm
@PaŭloEbermann, I want to store it in a file so that the next time program runs I won't have to enter it again (thus risking to learn a slightly different password every day).Ravin
@SethCarnegie He also said "password". A non-cryptographically-secure hash will leak information about the input string.Superfamily
Why this function isn't secure?Crap
oh. I guess it's not safe because we get only number. it's not hard to try all variantsCrap
It doesn't matter if the hash is cryptographically secure or not; in either case a simple hash of a password is highly vulnerable to brute force search. A proper salted, key-stretching password hash like PBKDF2, scrypt, bcrypt or Argon2 should be used.Lexicon
Since people are still finding this answer, I'd like to add, that since c++14 the produced hash is not guaranteed to be the same across multiple executions of the program. See note in en.cppreference.com/w/cpp/utility/hash, or section 20.5.3.4.1.3 of n4659 draft.Randirandie
Yes please downvote this answer as much as you can so it doesn't confuse people. Might have been correct in the past but not anymore for modern c++Have
C
42

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.

Clodhopper answered 18/9, 2016 at 9:15 Comment(3)
What does this line of code means std::hash<std::string>{}Rameriz
@Kapil calls the constructor for std::hash<std::string> type, which allocates an unnamed instance. then it calls its () operator.Scurrility
It seems to me that std::hash is not garanteed to be repeatable across different executions even on the same machine. Rather use MD5 or SHA256Have
B
3

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

Beghard answered 6/11, 2011 at 18:14 Comment(2)
Apart from the size issue, it is also probably not a cryptographically secure hash, i.e. knowing the implementation and a hash, it is quite easy to find a string which has this hash. You don't want this for password hashing.Algorithm
@PaŭloEbermann Agreed. The title of the question can be misleading. :)Beghard
S
0

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

Sprawl answered 21/2, 2021 at 10:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.