php - How to deal with integer max difference between 32 bit and 64bit servers? -
it takes long time figure out causing malfunctioning website of mine when migrating better hosting subscription.
i use 'self-made' uniqueid generator generate must unique uniqueness not random. use communicate between several services, generate reproducible unique 'numbers' files, articles , on.
this function have made , never had problems (i think never runs on 64bit system before?) generate unique id. know uniqueness limited (64.000) never lead problem until now.
function sugethashcode($s) { $hash=0; $c=(is_string($s))?strlen($s):0; $i=0; while($i<$c) { $hash = (($hash << 5)-$hash)+ord($s{$i++}); //hash = hash & hash; // convert 32bit integer } return ( $hash < 0 )?(($hash*-1)+0xffffffff):$hash; // convert unsigned int } function suuniqueid( $s, $baddlen = false ) { $i = base_convert( sugethashcode( $s ), 10, 32 ); if( $baddlen && is_string($s) ) { $i.=('-'.sugetlz( dechex( strlen($s)*4 ), 3 )); } return $i; } function sugetlz( $i, $imaxlen ) // leading 0 { if( !is_numeric( $i ) || $i < 0 || $imaxlen <= 0 ) { return $i; } $c = strlen( $i ); while( $c < $imaxlen ) { $c++; $i='0'.$i; } return $i; }
the max int value of integer on new system:
php_int_max = 9223372036854775807
on other system(s) is:
php_int_max = 2147483647
well, not math person, think causing problem because of 0xffffffff increment when negative (i think never negative on new system).
but how can change function produces same unique id's on other systems?
for example: produces same id different strings on new hosting server:
$sthisurl = '<censored>'; var_dump( suuniqueid($sthisurl) ); // produce: 1l5kc37uicb $sthisurl = '<censored>'; var_dump( suuniqueid($sthisurl) ); // produce same id above: 1l5kc37uicb
but, must on older systems:
$sthisurl = '<censored>'; var_dump( suuniqueid($sthisurl) ); // produce: a46q6nd $sthisurl = '<censored>'; var_dump( suuniqueid($sthisurl) ); // produce: 2mirj1h
notice: string seperate parts avoid stackoverflow see link.
edit: removed filenames
does how deal problem?
i suggest truncate after every character processed:
$hash = (($hash << 5)-$hash)+ord($s{$i++}); $hash = $hash & 0xffffffff; // convert 32bit integer
at least on 64bit system leads desired 2mirj1h
in second example, although without modification got 1c6ta2qjga7
, not 1l5kc37uicb
did.
i'd change return value return $hash
. either can represent unsigned 32bit numbers correctly, preceding mask should force interpretation. or system can't represent these, added computation won't there either, , you'd have split number bit groups , stringify them individually.
of course, easiest solution use established common hashing algorithm, e.g. using the hash
function. add secret salt if feat might open attacks. if result of such hash code long, can take part of output. can convert base way like, won't have use hexadecimal notation common hashes. using cryptographic hash reduce chances of conflict; example in case document generbm.js
in same path yield same hash.
Comments
Post a Comment