linux - 我可以使用什么算法来生成唯一 MAC 地址的 48 位哈希值?

标签 linux hash mac-address

有没有简单易用的哈希算法来生成48位哈希?我需要从唯一的输入字符串生成唯一的 MAC 地址。这里不存在安全问题,只是将其映射到 MAC 地址空间(48 位)的问题。

我想到了 CRC32,它只有 32 位并且很简单(每个 Linux 上都有 cksum),并将它们用于较低的 32 位,但如果它更多,冲突会非常高比几个主机。

如果我可以获得 48 位哈希值,我可以屏蔽 8 个最高有效位中的第二个最低有效位,以确保它是本地管理地址。单个比特的损失很小。

相反,我可以使用更长的哈希算法(MD5、SHA1 等),只取 48 个最高有效位或最低有效位。

有没有简单的方法可以做到这一点?

我更喜欢命令行实用程序,但如果我必须编写简短的 python 或类似的东西,没什么大不了的。

最佳答案

两年后,这是一个在实际应用中的想法(非常接近您所需要的)。

我只需要一个没有非 volatile 存储器的定制板的 48 位序列号。该板采用 STM32 处理器,具有 96 位唯一 ID (STM32_UUID)。

这是完整的 C 代码:

#define STM32_UUID                      ((uint8_t*)0x1FFFF7E8)

// board SN 48 bit
static uint8_t BoardSerial[6]; 

void setBoardSerial(void)
{
  uint64_t hash = fastHash64(STM32_UUID, 12, 1234554321);
  memcpy(BoardSerial, &hash, 6);
}

static inline uint64_t mix(uint64_t h)
{
    h ^= h >> 23;
    h *= 0x2127599bf4325c37ULL;
    h ^= h >> 47;
    //
    return h;
}

uint64_t fastHash64(const void * buf, size_t len, uint64_t seed)
{
    const uint64_t m = 0x880355f21e6d1965ULL;
    const uint64_t * pos = (const uint64_t*)buf;
    const uint64_t * end = pos + (len / 8);
    const unsigned char * pos2;
    uint64_t h = seed ^ (len * m);
    uint64_t v;

    while(pos != end)
    {
        v  = *pos++;
        h ^= mix(v);
        h *= m;
    }

    pos2 = (const unsigned char*)pos;
    v = 0;

    switch(len & 7)
    {
        case 7: v ^= (uint64_t)pos2[6] << 48;
        case 6: v ^= (uint64_t)pos2[5] << 40;
        case 5: v ^= (uint64_t)pos2[4] << 32;
        case 4: v ^= (uint64_t)pos2[3] << 24;
        case 3: v ^= (uint64_t)pos2[2] << 16;
        case 2: v ^= (uint64_t)pos2[1] << 8;
        case 1: v ^= (uint64_t)pos2[0];
                h ^= mix(v);
                h *= m;
    }

    return mix(h);
}

我在一批大约 200 个单元(板)上测试了这个解决方案,绝对没有问题,没有冲突。我见过很多人遇到这个问题,当他们需要一个较小的设备 ID 时,该 ID 不知何故源自一个大的唯一设备序列号。

或者,您可以搜索 Bobcat 48 位哈希 的实现。

关于linux - 我可以使用什么算法来生成唯一 MAC 地址的 48 位哈希值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32252996/

相关文章:

node.js - 如何使用node.js获取连接到WiFi的所有MAC地址?

Perl,将字符串拆分为 key :Value pairs for hash with lowercase keys without temporary array

MySQL 服务器最大化内存,Galera 集群

php - 在后台运行脚本并从 php 返回它的 pid

java - 亚马逊 ec2-ebs-mySql-CouchDB-ldap

regex - 如何有效地处理同一字符串上的多个 Perl 搜索/替换操作?

python - 压缩和比较 Python 列表的高效准确方法?

embedded - MAC 地址有多独特

ios - Apple 拒绝了应用程序,因为它在未经用户许可的情况下传输 MAC 地址

linux - sockaddr_in 和 sockaddr_in6 还在使用 sin_len 和 sin6_len 吗?