【发布时间】:2013-10-06 21:38:34
【问题描述】:
在迁移到更好的托管订阅时,要找出导致我的网站出现故障的原因需要很长时间。
我使用“自制”的 uniqueId 生成器来生成必须唯一但这种唯一性不是随机的所有内容。我使用它在多个服务之间进行通信,为文件、文章等生成可重现的唯一“数字”。
这是我制作的功能,并且从未遇到过问题(我认为它以前从未在 64 位系统上运行过?)来生成唯一的 id。我知道这种唯一性是有限的(64.000),但直到现在才导致问题。
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 to 32bit integer
}
return ( $hash < 0 )?(($hash*-1)+0xFFFFFFFF):$hash; // convert to 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 zero
{
if( !is_numeric( $i ) || $i < 0 || $iMaxLen <= 0 )
{ return $i; }
$c = strlen( $i );
while( $c < $iMaxLen )
{ $c++; $i='0'.$i; }
return $i;
}
整数的最大 int 值在新系统上:
PHP_INT_MAX = 9223372036854775807
在其他系统上是:
PHP_INT_MAX = 2147483647
好吧,我不是数学家,我认为这是因为负数时 0xFFFFFFFF 增量(我认为在这个新系统上永远不会是负数)导致了问题。
但是我怎样才能改变它在其他系统上产生相同的唯一 ID 的功能呢?
例如: 它为新托管服务器上的不同字符串生成相同的 id:
$sThisUrl = '<censored>';
var_dump( suUniqueId($sThisUrl) ); // Produce: 1l5kc37uicb
$sThisUrl = '<censored>';
var_dump( suUniqueId($sThisUrl) ); // Produce the same id as above: 1l5kc37uicb
但是,这必须像在旧系统上一样:
$sThisUrl = '<censored>';
var_dump( suUniqueId($sThisUrl) ); // Produce: a46q6nd
$sThisUrl = '<censored>';
var_dump( suUniqueId($sThisUrl) ); // Produce: 2mirj1h
注意:字符串被分成几部分以避免堆栈溢出,请参阅此链接。
编辑:删除的文件名
有没有人可以解决这个问题?
【问题讨论】:
-
没有必要说“编辑:删除 X”,因为它只是将注意力吸引到原始帖子 stackoverflow.com/revisions/19214266/1
-
在某些方面你是对的,但没关系,在示例中放置两个不同的长 url,你会看到它在 64 位上产生相同的结果。
-
您无法轻易收回您在 cc-by-sa 许可下发布的内容。编辑问题会使其不那么显眼,但原始形式的问题不再是您的专属财产。此外,删除字符串会使其他人难以重现此问题。而且由于手头很少有人安装 32 位和 64 位的 PHP,这大大减少了比较的机会。
-
@MvG:关键是该函数产生相同的 id,无论输入是什么,其中的 url 只是一个示例。您可以简单地将一些不同的 url 放入示例中,函数的行为保持不变。
标签: php math 32bit-64bit uniqueidentifier