您可能知道可以通过以下方式生成 MAC 地址:
macaddr=$(dd if=/dev/random bs=1024 count=1 2>/dev/null|md5sum|sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\)\(..\).*$/\1:\2:\3:\4:\5:\6/')
echo $macaddr
但这种方法可能会产生如下所示的 MAC 地址:07:d4:51:9f:50:6c
。您根本无法使用该地址。如果您尝试过,您会收到此错误:
# ip link set dev wlan0 address $macaddr
RTNETLINK answers: Cannot assign requested address
所以上面的行应该重写。问题是它应该是什么样子才能使 MAC 地址始终有效?
答案1
- 提取第一个字节(例如
07
从您的示例中) - 按位与十进制 254(11111110 - 除第零位设置之外的所有位)
- 按位或与十进制 2(00000010 - 仅设置第 1 位)
- 将第一个字节与最后五个字节组合起来
例如
#! /bin/sh
mac='07:d4:51:9f:50:6c'
lastfive=$( echo "$mac" | cut -d: -f 2-6 )
firstbyte=$( echo "$mac" | cut -d: -f 1 )
# make sure bit 0 (broadcast) of $firstbyte is not set,
# and bit 1 (local) is set.
# i.e. via bitwise AND with 254 and bitwise OR with 2.
firstbyte=$( printf '%02x' $(( 0x$firstbyte & 254 | 2)) )
mac="$firstbyte:$lastfive"
echo "$mac"
输出:
06:d4:51:9f:50:6c
07
十六进制是00000111
二进制。按位与254
(11111110
二进制)结果为00000110
二进制(十进制 6)。与2
(二进制)进行按位或运算00000010
不会导致任何变化,因为位 1 已设置。最终结果是06
十六进制。