2

I am looking for a way to hash a user id, obtained from a 3rd party service, such that I can use the hash as a primary key.

My understanding is that the usual SHA-512 style algorithms, given an input string that is guaranteed to be unique, are not guaranteed to produce a hash value that is also guaranteed to be unique.

Is there a hashing algorithm that will produce an unique hash?

More specifically is there such an algorithm supported out of the box by NodeJS 10.9 or better

Dave Sag
  • 13,266
  • 14
  • 86
  • 134
  • 3
    Given that the range of a typical hashing algorithm is limited while you can feed infinitely many inputs in, getting a 'unique' hash is difficult. Of course, actually getting a collision from two random input strings is so unlikely that it probably won't happen unless you're purposefully trying to find a collision. – Andrew Fan Aug 29 '18 at 03:59
  • I imagine that the output for any such hashing function that fulfills your requirements would have its length scale with the length of your input, since the input set has to be one-to-one with the output set. – CertainPerformance Aug 29 '18 at 04:05
  • 1
    A hash, somewhat by definition, has a non-zero probability of collision, so it's not guaranteed to be unique. If you want unique-ness guarantee, then you will want to use something other than a hash, like perhaps encrypt the userID or something like that and it will have to scale with the length of the input. If you're willing to deal in probabilities (not guarantees), then you can likely find a hash that has a low enough probability of non-uniqueness, but what exactly would work depends upon a lot of details and requirements you have not shared. – jfriend00 Aug 29 '18 at 04:06
  • 1
    512 bits is a lot of bits... Look at [this relevant question](https://crypto.stackexchange.com/a/47810/27611) for SHA-256 and then consider that with SHA-512 that space is **squared**. – Luke Joshua Park Aug 29 '18 at 04:16

2 Answers2

2

Length of a SHA-512 hash is 64 bytes(512 bits) long which gives you 10154 combinations of values. So it has a very less (i mean a very very less ) chance of getting same hash.

How much very less it is, think of the weight of the sun from grams (which is weigh million times like the earch). If any other planet weight 10154 of grams, not even a millions of millions suns combined can be equals to that amount.

So by very less, it means never. Even the bitcoin addresses are using this method as the wallet address. If you by any chance can find that one combination, you will be a billionaire. I promise

enter image description here

Janith
  • 2,730
  • 16
  • 26
  • 1
    I think you intended to write 512 bits in your first sentence. – Luke Joshua Park Aug 29 '18 at 04:26
  • @LukeJoshuaPark Yeah, Thanks – Janith Aug 29 '18 at 04:31
  • @DaveSag The theory would stay if the hash output would be uniform, but it is not. https://michiel.buddingh.eu/distribution-of-hash-values Regardless that - the collision probability of SHA-256 is IMHO negligible, though in principle not guaranteed to be unique – gusto2 Aug 29 '18 at 07:14
  • Thanks and yes I am pretty confident that SHA-512 will suit my needs. The commercial impact of a collision is actually quite small so the tiny risk is worth taking. – Dave Sag Aug 30 '18 at 02:57
1

Most hashing algorithms are doing their best to avoid collisions. SHA 512 ought to be fine for you, if not SHA 256. Note that if you can see collisions in the input data, there will be collisions in the hashes, in which case I recommend appending something else likely unique to two separate accounts - such as the timestamp they were created - before inputting the value into the hash. This will work just fine so long as both inputs are immutable and they never change on the account.

You can use crypto.getHashes() to view available hashes and pick the one you want. You are asking after uniqueness and not security so faster is better.

This answer is also related: When using SHA-256 hashes as a primary key, is it OK to ignore the possibility of collisions?

Catalyst
  • 3,143
  • 16
  • 20