I suggest you truncate after every character is processed:
$hash = (($hash << 5)-$hash)+ord($s{$i++});
$hash = $hash & 0xFFFFFFFF; // Convert to 32bit integer
At least on my 64bit system this leads to the desired 2mirj1h
in your second example, although without this modification I got 1c6ta2qjga7
and not 1l5kc37uicb
as you did.
I'd also change the return value to simply return $hash
. Either it can represent unsigned 32bit numbers correctly, then the preceding mask should force that interpretation. Or your system can't represent these, then the added computation won't get you there either, and you'd have to split the number into bit groups and stringify them individually.
Of course, the easiest solution would be to use some well established common hashing algorithm, e.g. using the hash
function. Add some secret salt if you feat this might open you to attacks. If the result of such a hash code is too long, you can simply take part of the output. You can convert base any way you like, so you won't have to use the hexadecimal notation common for hashes. Using a cryptographic hash would also reduce chances of a conflict; for example in your case the document generbM.js
in the same path would yield the same hash.