我正在使用接收非常小的数据包的设备。设备由48位密钥唯一标识。当设备接收到单个数据包时,它需要读取数据包并确定数据包是否适用于该设备。听起来很简单,但数据包有足够的空间只能容纳16位密钥。
无法更改通信协议。我无法使用数据包中的多个数据包或任何其他字段。基本上我需要将这个48位标识符存储在16位字段中。显然,任何解决方案都会发生冲突。
我正在考虑发送原始密钥的低16位或散列它。 在最小化碰撞的同时,最好的方法是什么?
PS:实际上看起来原始密钥的前三个字节总是相同的,所以这个问题只是减少了将24位密钥推入16位密钥,但仍然很糟糕。
PPS:碰撞不是灾难性的。该设备可以恢复,但价格昂贵。答案 0 :(得分:0)
在这种情况下唯一可以帮助您的是,如果您的设备小于或等于2^16
。在这里,您需要具有将每个24-bit
键映射到唯一16-bit
键的哈希表。因此,在发送数据包时发送16-bit
密钥,同时检索哈希表中的密钥映射值检查。您还可以对16-bit
键值进行硬编码以进行直接比较。
但是如果您有超过2 ^ 16个设备,那么根据鸽子洞原则,您将拥有2个或更多具有相同16-bit
密钥的设备,那么您无法确定数据包所针对的设备。
发送的伪代码&接收数据包: -
Send(BigKey,Data) {
// get 16-bit key from 24-bit one
SmallKey = HashMap.getValue(BigKey);
Packet = SmallKey + Data ;
}
Receive(Packet) {
(Key,Data) = split(Packet);
// get devices 16-bit key
SmallKey = HashMap.getValue(MyKey);
if(SmallKey==Key)
Process(Data)
else Error("Invalid Packet");
}
注意: - 可以使用红黑树,b树等在O(logn)中进行查找来创建哈希映射。这对你的应用来说已经足够了。
答案 1 :(得分:0)
询问制造商有关生成此编号的任何模式。这些24位中的一些很可能识别出生产批次或世界的一部分,这使得它们成为被削减的主要候选者。
在请求中明确表示您已了解并接受他们可以随时更改编号政策,恕不另行通知。这应该使他们更有可能提供信息。