【问题标题】:Hashing a 48-bit key into a 16-bit value将 48 位密钥散列为 16 位值
【发布时间】:2013-12-12 12:46:52
【问题描述】:

我正在使用接收非常小的数据包的设备。设备由 48 位密钥唯一标识。当设备接收到单个数据包时,它需要读取数据包并确定该数据包是否用于该设备。听起来很简单,但数据包只有一个 16 位密钥的空间。

无法更改通信协议。我无法使用多个数据包或数据包中的任何其他字段。基本上我需要将这个 48 位标识符存储在一个 16 位字段中。显然,任何解决方案都会发生冲突。

我正在考虑要么发送原始密钥的低 16 位,要么对其进行哈希处理。 在最小化碰撞的同时做到这一点的最佳方法是什么?

PS:实际上看起来原始密钥的前三个字节总是相同的,所以这个问题只是简化为将 24 位密钥推入 16 位密钥,但仍然很糟糕。

PPS:碰撞不是灾难性的。该设备可以恢复,但价格昂贵。

【问题讨论】:

  • 在尽量减少冲突的同时做到这一点的最佳方法是什么?”如果不了解所用值的分配和分布,这是不可能回答的。
  • 如果私钥是随机生成的,对它们进行散列处理不会导致比抓取 16 位小节更少的冲突。如果这很重要,最好隐藏密钥。
  • 单个设备是否可编程?你能配置设备告诉它它的 16 位密钥是什么吗?如果您事先知道所有设备 ID,则可以创建一个 minimal perfect hash。但是如果没有某种方式告诉设备寻找特定的数据包编号,冲突的机会将是非零的。
  • 另外,你能估计一下你认为最终会被使用的密钥数量吗?鉴于此,不难计算发生碰撞的概率。

标签: algorithm math hash integer mac-address


【解决方案1】:

向制造商询问此号码生成过程中的任何模式。这 24 位中的一些很可能标识了生产批次或要运送到世界的哪个部分,从而使它们成为被修剪的主要候选者。

在请求中明确说明您知道并接受他们可以随时更改编号政策,恕不另行通知。这应该使他们更有可能提供信息。

【讨论】:

    【解决方案2】:

    在这种情况下,唯一可以帮助您的是您的设备小于或等于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-tree 等创建哈希映射,这些树在 O(logn) 中进行查找。这对于您的应用程序来说已经足够了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-11
      • 2023-01-28
      • 2014-11-03
      • 2015-12-31
      • 1970-01-01
      • 2011-01-27
      • 2012-07-01
      相关资源
      最近更新 更多