从IP地址创建唯一号码的最佳方法是什么?
19.22.145.103
我计划将每个八位字节相加以得到唯一的数字,但看起来我可能没有为每个IP地址获取唯一的数字。
Sum of each octet 19 + 22 + 145 + 103 = 289 as the unique number.
我已经知道我们无法将IPv4映射到16位,因此可以接受更少冲突的解决方案。我正在寻找下面两点提到的解决方案。
short
数据类型中存储此唯一编号。由于short是16位,因此我们可能无法将IPv4映射为唯一的short。如果我们仍然使用short
数据类型而不是像我上面使用的那样使用每个八位字节的总和,还有其他方法我们可以提出更少的冲突吗?我的所有IP地址都以10.
开头,如果有助于确定算法,那么碰撞就会减少。
答案 0 :(得分:1)
IPv4是4个八位字节,因此您可以使用类似
的内容获得唯一的映射public static int asInt(byte[] addr) {
return (addr[0] & 0xFF) | ((addr[1] & 0xFF) << 8)
| ((addr[2] & 0xFF) << 16) | ((addr[3] & 0xFF) << 24);
}
或
public static int asInt(byte[] addr) {
return ByteBuffer.wrap(addr).readInt();
}
这为您提供了2 32 可能的值。如果你想将它映射到16位并确保它是唯一的,你需要将映射存储在其他地方,例如。
final Map<Integer, Short> mapping = new ConcurrentHashMap<>();
int next = 0;
public short idFor(byte[] bytes) {
Integer i = asInt(bytes);
return mapping.computeIfAbsent(i, x -> next++);
}
在Java 7上,你可以做到
public short idFor(byte[] bytes) {
Integer i = asInt(bytes);
synchronized(mapping) {
Short s = mapping.get(i);
if (s == null)
mapping.put(i, s = next++);
return s;
}
}
注意,16位值只能有65536个可能的唯一值。
如果你想要一个简单的哈希,你可以使用像
这样的东西public short hash(int n) {
return (short) (n ^ (n >>> 16))
}
您可以添加像
这样的aggetate函数public short hash(int n) {
n *= 10191; // an odd prime of around 2^^16
return (short) (n ^ (n >>> 16))
}
不理想的是顶部位不会以这种方式产生很多随机性。您可以改为使用64位计算。
public short hash(int n) {
long n2 = n * 0x6d0f27bdL;
n2 ^= (n2 >>> 21) ^ (n2 >>> 42);
return (short) (n ^ (n >>> 16) ^ (n >> 32));
}
答案 1 :(得分:0)
您的任务通常不可能。所以我会从业务领域寻找快捷方式。
您是否需要映射所有 IP地址?您可以跳过127.*.*.*
和192.168.*.*
。但这还不够。您需要减少到16位,这是整个范围的摩擦:1 / 2^16
〜1 / 64000
答案 2 :(得分:-1)
我有一种新的方式..查看代码,它可以保证您的代码将是独一无二的......
@model IEnumerable<WebApplication1.Models.EmployeeProject>
....
<table class="table">
<tr>
<th>@Html.DisplayNameFor(model => model.EmployeeName)</th>
<th>@Html.DisplayNameFor(model => model.ProjectName)</th>
....
</tr>
@foreach (var item in Model)
{
using (Html.BeginForm("Edit","EmployeeProject",item))
{
@Html.AntiForgeryToken()
<tr>
@Html.ValidationSummary(true)
@Html.HiddenFor(model => item.EmployeeProjectID)
@Html.HiddenFor(model => item.EmployeeID)
@Html.HiddenFor(model => item.ProjectID)
<td>
@Html.DisplayFor(model => item.EmployeeName)
@Html.ValidationMessageFor(model => item.EmployeeName)
</td>
<td>
@Html.DisplayFor(model => item.ProjectName)
@Html.ValidationMessageFor(model => item.ProjectName)
</td>
....
<td class="form-group">
<td class="col-md-offset-0 col-md-5">
<input type="submit" value="Save" />
</td>
</td>
</tr>
}
}
</table>