I needed to somehow generate a hash from a string but the same hash is obtained regardless of the order of the two strings
1234+4321 = asdfghjkl
4321+1234 = asdfghjkl
Is this possible with PHP?
I needed to somehow generate a hash from a string but the same hash is obtained regardless of the order of the two strings
1234+4321 = asdfghjkl
4321+1234 = asdfghjkl
Is this possible with PHP?
I see two options: 1) you compare both strings, and concatenates them so that the "minor" (in lexicographic order) is always first, and then makes the hash of the strings concatenated; 2) you make the hash of each string independently, and then combine the results using some commutative operation (like an xor). Examples:
function hashPar1($a, $b) {
if ( strcmp($a, $b) > 0 ) {
$temp = $a;
$a = $b;
$b = $temp;
}
return hash("sha256", $a . $b);
}
function hashPar2($a, $b) {
$ha = hash("sha256", $a);
$hb = hash("sha256", $b);
$ret = "";
for( $i=0; $i<strlen($ha); $i++) {
ret .= chr(ord($ha{$i}) ^ ord($hb{$i}))
}
return ret;
}
Note: I suggest the second option because the first method has the disadvantage of a larger number of collisions. For example, foo+bar
would produce the same hash of fo+obar
or f+oobar
or fooba+r
(but not foob+ar
). This problem does not occur in the second method, since distinct strings would have totally different hashes [with high probability].
Update: I just read a comment saying which in PHP you can do the xor of two strings directly, do not need to break it into characters and convert to and from numbers. If this is correct (did not test) then the code of option 2 can be simplified to:
$resultado = hash("sha256", $string1) ^ hash("sha256", $string2);
Sort the String and use the hash function. See the code below
>>> a = '1234+4321'
>>> b = '4321+1234'
>>> a
'1234+4321'
>>> b
'4321+1234'
>>> sorted_a = ''.join(sorted(a))
>>> sorted_a
'+11223344'
>>> sorted_b = ''.join(sorted(b))
>>> sorted_b
'+11223344'
>>> hash(sorted_a)
6594644838925616234
>>> hash(sorted_b)
6594644838925616234
Note that the above code works for letters and numbers. The procedure used was as follows:
Note: The original question does not specify the lingaugem, so I did in python.