0

我有一个董事会,我想禁用注册,而不是希望用户能够使用基于其 IPAddress 的唯一 ID 自由发布

例如:

如果“Joe”IP 为 200.100.15.117,“Joe”昵称将成为 200.100.15.117 的哈希函数

如果“Joe”IP 发生变化,他将获得另一个 ID,没关系,我只希望每个 IPAddress 有一个唯一 ID

还有两件重要的事情:

  • 唯一 ID 必须为 8 个字符长
  • 哈希应该是安全的,我不希望黑客能够破解我的用户 IP 地址

我想使用 MD5 函数,然后将其修剪为 8 个字符,但这有多独特?有没有更好的办法 ?

4

4 回答 4

2

您可以将 ip 地址字符串转换为 LONG(4 字节),然后做任何您想做的事情。

请参阅 php 函数ip2long

于 2012-10-29T09:15:21.733 回答
1

问题是你不能真正区分同一网络上的两个人,所以如果我在那里发帖,而我的宿舍邻居访问该网站,该网站认为他是我。

您应该考虑使用 cookie,它们很容易变得独一无二,而且 AFAIK 不能被远程黑客入侵。

对于唯一 ID 部分,如果您将“用户”存储在数据库中,您可以只从“用户”表中分配主键并在 cookie 中使用它。

如果它必须是 8 个字符长,您可以在 ID 前添加 0 - 例如 00000001、00000002 .... 至少这样它是独一无二的,并且 8 个字符长 -

于 2012-10-29T09:07:17.977 回答
0

编辑根据 OP 对此答案的评论。

下面的代码使用 BC Math 库将 MD5 哈希转换为 Base-90 字符串。这会将 32 个字符的字符串转换为 20 个字符的字符串。这与所需的 8 个字符相去甚远,但它是使用 ASCII 范围的最小字符串长度(可以通过使用字符将基数增加到 Base-94,' " \ [space]但这不会影响字符串长度,而是可能在处理数据时导致问题) .

$ip      = '200.100.15.117';
$hash    = md5($ip);
$chars16 = array(
    '0' => 0,  '1' => 1,  '2' => 2,  '3' => 3, '4' => 4,  '5' => 5,
    '6' => 6,  '7' => 7,  '8' => 8,  '9' => 9, 'a' => 10, 'b' => 11,
    'c' => 12, 'd' => 13, 'e' => 14, 'f' => 15
);
$base10 = '0';
for ($i = strlen($hash) - 1; $i > 0; $i--) {
    $base10 = bcadd($base10, bcmul($chars16[$hash[$i]], bcpow(16, $i)));
}
$chars   = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,;.:-_+*?!$%&@#~^=/<>[](){}`';
$base    = (string)strlen($chars);
$baseX   = '';
while (bccomp($base10, $base) === 1 || bccomp($base10, $base) === 0) {
    $baseX  = substr($chars, bcmod($base10, $base), 1) . $baseX;
    $base10 = preg_replace('/\.\d*$/', '', bcdiv($base10, $base));
}
$baseX = substr($chars, $base10, 1) . $baseX;
echo $baseX; // Shows: 1BS[JdZf/7J$J{ud&r5i
于 2012-10-29T11:12:32.957 回答
0

您可以对 IP 地址加盐,例如

$salt = "e45re%$#";
$ip = "200.111.123.111";
$hash = md5($ip.$salt);

$hash = substr($hash,0,8); 
于 2021-03-10T13:21:43.960 回答