有一些很好的答案,但对我来说这些方法似乎很愚蠢。
他们首先强制php创建一个十六进制数字,然后在BigInteger中将其转换回来(hexdec
),然后将其减少为多个字母......这是很多工作!
相反何不
阅读散列作为二进制:
$binhash = md5('[input value]', true);
然后使用
$numhash = unpack('N2', $binhash); //- or 'V2' for little endian
施放此为两个INT
S($numhash
是两个元件的阵列)。现在只需使用AND
操作即可减少数字中的位数。例如:
$result = $numhash[1] & 0x000FFFFF; //- to get numbers between 0 and 1048575
但是要警告碰撞!减少数字意味着增加具有相同输出的两个不同[输入值]的概率。
我认为更好的方法是使用带有Bijectiv函数的“ID-Crypting”。所以不会发生碰撞!对于最简单的一种只需使用一个Affine_cipher
实施例与最大输入值范围从0到25:
function numcrypt($a)
{
return ($a * 15) % 26;
}
function unnumcrypt($a)
{
return ($a * 7) % 26;
}
输出:
numcrypt(1) : 15
numcrypt(2) : 4
numcrypt(3) : 19
unnumcrypt(15) : 1
unnumcrypt(4) : 2
unnumcrypt(19) : 3
例如
$id = unnumcrypt($_GET('userid'));
... do something with the ID ...
echo '<a href="do.php?userid='. numcrypt($id) . '"> go </a>';
当然
这是不是安全的,但如果没有人知道使用您的加密方法则没有安全原因,那么这种方式速度更快,安全碰撞。
如果我将“测试”变量限制为一组有限的数字,该怎么办? 会有减少散列大小的方法吗? – 2010-07-31 19:27:55
@YuriKolovsky - 最终的散列大小将取决于您在第二步中用于模块化分区的任何上限。例如,如果你想让你的哈希长度都是5位数,那么你可以使用'$ smallnum = $ bignum%99999'。无论放入初始MD5或SHA1哈希值如何,这都可以工作。 – derekerdmann 2010-07-31 19:33:18
@derekerdmann这看起来就像我需要的东西:D – 2010-07-31 19:35:06