Как сгенерировать действительный и случайный MAC-адрес?

Вероятно, вы знаете, что 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 из вашего примера)
  2. побитовое И это с десятичным числом 254 (11111110 – все биты, кроме набора нулевого бита)
  3. побитовое ИЛИ с десятичным числом 2 (00000010 – только 1 бит)
  4. объединить первый байт с последними пятью байтами

например

 #! /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. # ie 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 hex – 00000111 двоичный. побитовое И-ing с 254 ( 11111110 двоичный) приводит к двоичному 00000110 (6 десятичных знаков). побитовое ИЛИ – с 2 ( 00000010 код 00000010 ) не приводит к изменению, поскольку бит 1 уже установлен. Конечный результат – 06 hex.