is it possible to extract a "hint hash" of some kind from another hash? I'm a web developer starting to dip into cryptography so please bare with me on this...

Let's say I have a collection of hashes that were generated from some common data i.e. changes to multiple records. Is there a way that I could generate a secondary hash from the main hash and compare it to the other hashes based on how the main hash was generated. For example...

plain text             | hash      | hint hash
----------------------------------------------
"USER:123:fName:Alice" | 92eb5ff.. | 3cd24
"USER:123:fName:alice!"| 1c77753.. | 3cd24
"USER:456:fName:Bob"   | fee6ae2.. | 7d28e
"USER:456:fName:bob!"  | 7775315.. | 7d28e
"USER:789:fName:Carl"  | fec3ad7.. | 75315


Notice how all hashes are unique but the hint hashes match up to the record IDs they are hashed from. So if I generated these hashes based on the plain text and some key i.e. genHash(plainText, keyText). If you only had the hashes, you could associate which hashes are related to each other by their hint hashes only. So if I only had the hashes, I could still find their associations with a couple getHintHash(hash) calls...

Table of hashes:

hash      
---------
92eb5ff.. 
1c77753..
fee6ae2..
7775315.. 
fec3ad7..


Table of hashes with hint hashes:

hash      | hint hash
----------------------
92eb5ff.. | 3cd24
1c77753.. | 3cd24
fee6ae2.. | 7d28e
7775315.. | 7d28e
fec3ad7.. | 75315


Now I have the relationships between the unique hashes without exposing the plain text that generated them. Is this possible? Remember, the hashing function got the plaintext and a key that the "hint hash" could be based off of...

genHash("USER:123:fName:Alice", "USER:123") -&gt; 92eb5ff..
Cryptographic hash functions are designed to have certain properties, which is collision resistance, preimage resistance and second preimage resistance. If those definitions are not clear, we could state informally:

If you only have hash values of some input data, then you can't do anything except check for equality. You can't compare the input data, you can't check if they have a common substring, and most importantly you can't get back the input from the hash. So imagine a hash function as a one-way street, where you can afterwards just check for equality. Any other structure is lost.

And this is the behavior, which is wanted from cryptographic hashes.

So if you consider your database, when you have access to the plain text, you could just use a hash function with only the user ID as input:


$h_1 = hash(FullPlaintext)$
$h_2 = hash(User ID)$
Save tuples $(h_1,h_2)$, e.g. in a table


If you want to add some keys to those inputs, you have to consider that using a different key means getting a different example, and there is no way to tell if just part of the input was equal or not. But with this table you could do your lookups. But it is impossible to get $h_2$ from $h_1$ or vice versa. In a cryptographic hash function, you simply can't go backwards.