Give same value independent of the order

3

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?

    
asked by anonymous 02.07.2015 / 01:15

2 answers

3

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);
    
02.07.2015 / 01:54
0

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:

  • Variables 'a' and 'b' were created.
  • Variables 'a' and 'b' have been ordered so that they are the same if they have the same letters.
  • The hash has been calculated. If they have the same letters, they will have equal hashed values.
  • Note: The original question does not specify the lingaugem, so I did in python.

        
    02.07.2015 / 01:51