31

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?

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Septagram
  • 9,425
  • 13
  • 50
  • 81
  • 3
    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. – Paŭlo Ebermann Nov 06 '11 at 18:28
  • @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. – Septagram Nov 06 '11 at 18:32
  • 4
    **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). – Matthieu M. Nov 06 '11 at 19:09
  • 4
    @Septagram read http://xkcd.com/936/ – Seth Carnegie Nov 06 '11 at 19:37

4 Answers4

41

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

Seth Carnegie
  • 73,875
  • 22
  • 181
  • 249
  • 8
    This isn’t a cryptographically secure hash. – Konrad Rudolph Nov 06 '11 at 18:08
  • 37
    @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. – Seth Carnegie Nov 06 '11 at 18:10
  • 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. – Septagram Nov 06 '11 at 18:15
  • @Septagram 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). – Seth Carnegie Nov 06 '11 at 18:20
  • So it's _possible_ that it's reversible with an entropy of, say, 96 bits? – Septagram Nov 06 '11 at 18:22
  • I have no idea, sorry, I know less than nothing about cryptography. @KonradRudolph can you answer his question? – Seth Carnegie Nov 06 '11 at 18:24
  • @Septagram 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: http://www.packetizer.com/security/sha1/ – Seth Carnegie Nov 06 '11 at 18:31
  • @Septagram 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.) – Paŭlo Ebermann Nov 06 '11 at 18:34
  • @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). – Septagram Nov 06 '11 at 18:53
  • @SethCarnegie He also said "password". A non-cryptographically-secure hash _will_ leak information about the input string. – Nick Johnson Nov 06 '11 at 23:36
  • Why this function isn't secure? – Tebe Mar 11 '12 at 20:46
  • oh. I guess it's not safe because we get only number. it's not hard to try all variants – Tebe Mar 11 '12 at 21:08
  • 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. – divegeek Feb 22 '16 at 20:29
  • 5
    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 https://en.cppreference.com/w/cpp/utility/hash, or section 20.5.3.4.1.3 of n4659 draft. – veprolet Jun 02 '20 at 14:50
  • 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++ – Mehdi Jun 01 '22 at 11:31
38

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.

ekad
  • 14,436
  • 26
  • 44
  • 46
Ou Wei
  • 381
  • 3
  • 2
  • 4
    What does this line of code means std::hash{} – PapaDiHatti May 19 '17 at 07:15
  • 11
    @Kapil calls the constructor for `std::hash` type, which allocates an unnamed instance. then it calls its `()` operator. – sorush-r Aug 29 '17 at 05:51
  • 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 SHA256 – Mehdi Jun 01 '22 at 11:29
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..

Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
Kashyap
  • 15,354
  • 13
  • 64
  • 103
  • 1
    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. – Paŭlo Ebermann Nov 06 '11 at 18:31
  • 1
    @PaŭloEbermann Agreed. The title of the question can be misleading. :) – Kashyap Nov 07 '11 at 21:53
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

vSzemkel
  • 624
  • 5
  • 11