Como gerar um endereço MAC aleatório válido com o shell bash

12

Como posso gerar um endereço MAC aleatório válido com o bash?

A primeira metade do endereço deve permanecer sempre igual a esta

00-60-2F-xx-xx-xx

apenas o valor x deve ser gerado aleatoriamente?

    
por NES 04.12.2010 / 16:00

13 respostas

16

Aqui está um peixe.

Este script de shell gerará a string aleatória que você procura:

#!/bin/bash
hexchars="0123456789ABCDEF"
end=$( for i in {1..6} ; do echo -n ${hexchars:$(( $RANDOM % 16 )):1} ; done | sed -e 's/\(..\)/-/g' )
echo 00-60-2F$end

Eu acabei de ter algo aqui que mostrou como executá-lo a partir da linha de comando, mas depois de olhar para a solução complicada de Dennis Williamson, vejo que a resposta que as pessoas esperam é aquela em que eles não precisam fazer qualquer trabalho em si.

    
por 04.12.2010 / 17:22
15

No passado, fiz isso usando:

echo 00-60-2F-$[RANDOM%10]$[RANDOM%10]-$[RANDOM%10]$[RANDOM%10]-$[RANDOM%10]$[RANDOM%10]

mas isso só os tornará no intervalo de 0 a 9. Para os meus propósitos, isso foi bom o suficiente.

Provavelmente, uma solução melhor seria usar printf:

printf '00-60-2F-%02X-%02X-%02X\n' $[RANDOM%256] $[RANDOM%256] $[RANDOM%256]

Veja como isso funciona:

  • O programa printf é baseado na função C "printf", que recebe uma "string de formatação" como o primeiro parâmetro e depois os parâmetros adicionais preenchem a string de formato.
  • % na string de formato introduz um "especificador de formato" que pode conter um ou mais caracteres informando como formatar os argumentos.
  • Um zero inicial (0) em um especificador de formato significa que a saída numérica resultante deve ser preenchida com zeros à esquerda até a largura especificada.
  • O 2 diz que o especificador deve ser exibido ocupando dois caracteres no valor de largura.
  • O X termina o especificador e indica que ele deve ser interpretado como um número e exibido como hexadecimal. Porque é maiúscula, as letras a-f devem estar em maiúsculas.
  • O \ n é uma nova linha - o printf interpreta a barra invertida como um código de escape que pode ser usado para exibir outros caracteres, geralmente caracteres complicados, como a nova linha.
  • Os caracteres restantes no especificador de formato são impressos literalmente, isso inclui o "00-06-2F-" inicial e os traços entre os especificadores de formato.
  • Os argumentos restantes são substituições de variáveis de shell (denotadas pelo $) e incluem uma expressão matemática que é um número aleatório (RANDOM) módulo 256. Isso resulta em um número aleatório entre 0 e 255.
por 05.12.2010 / 13:58
15
  1. Gere um int de tamanho apropriado da seguinte forma: link
  2. Converta para hexadecimal da seguinte forma: link
  3. Adicione os traços entre três blocos gerados aleatoriamente

#!/bin/bash
RANGE=255
#set integer ceiling

number=$RANDOM
numbera=$RANDOM
numberb=$RANDOM
#generate random numbers

let "number %= $RANGE"
let "numbera %= $RANGE"
let "numberb %= $RANGE"
#ensure they are less than ceiling

octets='00-60-2F'
#set mac stem

octeta='echo "obase=16;$number" | bc'
octetb='echo "obase=16;$numbera" | bc'
octetc='echo "obase=16;$numberb" | bc'
#use a command line tool to change int to hex(bc is pretty standard)
#they're not really octets.  just sections.

macadd="${octets}-${octeta}-${octetb}-${octetc}"
#concatenate values and add dashes

echo $macadd
#echo result to screen
#note: does not generate a leading zero on single character sections.  easily remediedm but that's an exercise for you

Ou em python:

from random import randint
def gen_mac_char():
  return hex((randint(0,16))).split('x')[1]
def gen_mac_pair():
  return ''.join([gen_mac_char(), gen_mac_char()])
def gen_last_half_mac(stem):
  return '-'.join([stem, gen_mac_pair(), gen_mac_pair(), gen_mac_pair()])
print(gen_last_half_mac('00-60-2F'))

Observe que a versão do Python usa apenas um campo de 16 amplos para gerar um caractere hexadecimal, para que você não precise se preocupar com o preenchimento de zero - abordagem corrigida para endereçar um comentário.

    
por 04.12.2010 / 16:14
9

Usando ferramentas padrão,

# output in capitals
hexdump -n3 -e'/3 "00-60-2F" 3/1 "-%02X"' /dev/random

ou

# output in lower case letters
echo 00-60-2f$(od -txC -An -N3 /dev/random|tr \  -)

pode ser o mais curto de todos.

    
por 13.09.2012 / 11:19
6
#!/bin/bash
LC_CTYPE=C
MAC=00-60-2F
for i in {1..3}
do
    IFS= read -d '' -r -n 1 char < /dev/urandom
    MAC+=$(printf -- '-%02x\n' "'$char")
done
printf '%s\n' "$MAC"

As chaves para a maneira como isso funciona:

  • LC_CTYPE=C - permite caracteres > 0x7F
  • IFS= - desativa a interpretação de \t (tab), \n (newline) e espaço
  • -d '' - permite novas linhas
  • -r permite \ (e deve quase sempre ser usado pelo hábito com read )
  • O especificador de formato -%02x\n faz com que a saída seja um hífen literal seguido por um número hexadecimal de dois dígitos, incluindo um zero à esquerda, se apropriado. A nova linha é supérflua aqui e pode ser omitida.
  • O read obtém um único byte ( -n 1 ) de /dev/urandom no intervalo de 0 a 255 ( 00 to FF ).
  • A aspa simples no último argumento para o printf no loop faz com que o caractere seja emitido como seu valor numérico ("A" é exibido como "65"). Veja a especificação POSIX para printf onde diz:

    If the leading character is a single-quote or double-quote, the value shall be the numeric value in the underlying codeset of the character following the single-quote or double-quote.

por 04.12.2010 / 18:09
5

O caminho mais curto que eu pude fazer foi usar o hexdump diretamente

echo 00-60-2f$(hexdump -n3 -e '/1 "-%02X"' /dev/random)
  • -n3 diz ao hexdump para ler três bytes
  • A string de formato imprime um traço e um valor hexadecimal de dois dígitos para cada byte
    • '/ 1' significa aplicar formato para cada byte de leitura
    • "-% 02X" é uma especificação printf para imprimir um valor hexadecimal de zero, dois dígitos na parte superior
  • / dev / random é uma fonte de bytes aleatórios

Testado no GNU / Linux

    
por 06.09.2012 / 11:30
4

Outra solução de uma linha

$ echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /-/g'

Mesma coisa em maiúsculas

$ echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /-/g' | tr '[:lower:]' '[:upper:]'

Gere-o para uma variável de ambiente Bash

$ export MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /-/g')
$ echo $MAC

Detalhes:

  • od (octal dump)

    -An Suprime a representação do endereço principal (ruído extra) da saída.
    -N3 Limita a saída a três bytes.
    -t xC Saída em hexadecimal, estilo de caractere ASCII, conforme desejado. br> /dev/urandom pseudo-arquivo do número aleatório do kernel do Linux.

  • sed (editor de fluxo) Para espaço para substituição de hífen.

    -e <SCRIPT> executa o script sed.

  • tr (tradução de string) Opcional, neste exemplo. Eu gosto de endereços MAC maiúsculos em meus scripts / ambiente.

por 07.09.2012 / 04:59
2
#!/bin/bash
#Creates an array containing all hexadecimal characters
HEX=(a b c d e f 0 1 2 3 4 5 6 7 8 9)
#Defines MAC string length as 0 (total SL will be 17)
SL=0
#Loop sequentially assigns random hex characters in pairs until a full
#MAC address is generated.
while [ $SL -lt 17 ]
do
        num='shuf -i 0-15 -n 1' #Generates random number which will be used as array index
        RMAC="$RMAC""${HEX[$num]}" #Uses the randomly generated number to select a hex character
        num='shuf -i 0-15 -n 1' #New random number
        RMAC="$RMAC""${HEX[$num]}" #Appends second hex character
        SL=$['echo $RMAC | wc -c' - 1] #Calculates SL and stores in var SL
    if [ $SL -lt 17 ] #If string is uncomplete, appends : character
            then
            RMAC=""$RMAC":"
    fi
done
echo $RMAC #Displays randomly generated MAC address
    
por 25.08.2012 / 01:04
2

Isso deve funcionar

echo 00-60-2f-'openssl rand -hex 3 | sed 's/\(..\)/-/g; s/.$//''
    
por 20.09.2013 / 04:01
0
end=$( echo $RANDOM | openssl md5 | sed 's/\(..\)/-/g' | cut -b-8 )
echo 00-60-2f-$end
    
por 24.06.2011 / 23:37
0

Outra opção é usar jot :

echo 00-60-2F-$(jot -w%02X -s- -r 3 1 256)

-w altera o formato, -s altera o separador e -r gera números aleatórios.

Os comandos que usam od nas respostas publicadas por artistoex e zero2cx adicionam muitos traços extras à saída com od do OS X, mas isso não acontece:

echo 00-60-2f-$(od -tx1 -An -N3 /dev/random|awk '$1=$1'|tr \  -)

O od ( /usr/bin/od below) do OS X usa um formato de saída diferente do GNU od :

$ /usr/bin/od -N3 -tx1 -An /dev/random|tr ' ' -
-----------c7--fd--55----------------------------------------------------

$ god -N3 -tx1 -An /dev/random|tr ' ' -
-94-9e-5c
    
por 26.05.2016 / 10:07
0

Este também funciona. A saída está toda em maiúsculas, conforme necessário.

openssl rand -hex 3 | sed 's/\(..\)\(..\)\(..\)/00-60-2F---/' | tr [a-f] [A-F]
    
por 07.09.2016 / 10:23
0

Isso funciona no script shell clássico ( #!/bin/sh ):

random_mac() {
    printf '%.2x\n' "$(shuf -i 0-281474976710655 -n 1)" | sed -r 's/(..)/:/g' | cut -d: -f -6
}

Ou, se você quiser ter um prefixo personalizado:

random_mac_with_prefix() {
    echo -n "00:60:2f:" &&
    printf '%.2x\n' "$(shuf -i 0-281474976710655 -n 1)" | sed -r 's/(..)/:/g' | cut -d: -f -3
}

Exemplo de uso:

$ random_mac
96:ef:45:28:45:25
$ random_mac
7e:47:26:ae:ab:d4
$ random_mac_with_prefix 
00:60:2f:24:f4:18
$ random_mac_with_prefix 
00:60:2f:63:08:b2
    
por 28.12.2017 / 16:27