Respostas:
Aqui está um peixe.
Este script de shell irá gerar a sequência 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/\(..\)/-\1/g' )
echo 00-60-2F$end
Eu tinha apenas algo aqui que mostrava como executá-lo a partir da linha de comando, mas depois de olhar para a solução complicada (mas votada) de Dennis Williamson, vejo que a resposta que as pessoas esperam é aquela em que não precisam fazer nenhum trabalho si mesmos.
#!/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 python usa apenas um campo amplo de 16 para gerar um caractere hexadecimal, portanto você não precisa se preocupar com o preenchimento zero - abordagem alterada para abordar um comentário.
00-60-2F-8B-5-2C
, 00-60-2F-A-71-97
, 00-60-2F-82-F1-4
.
No passado, eu fiz isso usando:
echo 00-60-2F-$[RANDOM%10]$[RANDOM%10]-$[RANDOM%10]$[RANDOM%10]-$[RANDOM%10]$[RANDOM%10]
mas isso só os fará no intervalo de 0 a 9. Para 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:
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.
#!/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> 0x7FIFS=
- desativa a interpretação de \t
(tab), \n
(nova linha) e espaço-d ''
- permite novas linhas-r
permite \
(e quase sempre deve ser usado por hábito read
)-%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.read
recebe um único byte ( -n 1
) a partir /dev/urandom
da escala de 0 a 255 ( 00
a FF
).A citação simples no último argumento para o printf
loop faz com que o caractere seja exibido como seu valor numérico ("A" é exibido como "65"). Veja a especificação POSIX paraprintf
onde diz:
Se o caractere principal for uma aspas simples ou aspas duplas, o valor será o valor numérico no conjunto de códigos subjacente do caractere após a aspas simples ou aspas simples.
IFS= read …
de evitar dobrar 09 0a e 20 (os caracteres IFS usuais) em 00.
-d ''
. Eu vou consertar minha resposta. Obrigado por me avisar.
-r
que protege `\` caiu. Desejo que o tratamento adequado de dados binários em programas shell não seja tão complicado. Impossible Parece impossível representar com precisão 00 no meio da string. Seu método de caractere único por vez lida com 00 em virtude da cooperação conveniente (projetada?) Entre a read
interpolação de cadeias e como printf
trata o argumento de um caractere '
. Suspiro.
hexdump -C
.
A maneira mais curta que eu pude pensar foi usando o hexdump diretamente
echo 00-60-2f$(hexdump -n3 -e '/1 "-%02X"' /dev/random)
Testado no GNU / Linux
hexdump -n3 -e'/3 "00-60-2F" 3/1 "-%02X"' /dev/random
é um pouco mais curto :-)
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 (despejo octal)
-An
Suprime a representação do endereço principal (ruído extra) da saída.
-N3
Limite a saída para três bytes.
-t xC
Saída em hexadecimal, estilo de caractere ASCII, conforme desejado.
/dev/urandom
Pseudo-arquivo de número aleatório do kernel do Linux.
sed (editor de fluxo) Para espaço para hífen em substituição.
-e <SCRIPT>
execute o script sed.
tr (tradução de string) Opcional, neste exemplo. Eu gosto de endereços MAC em maiúsculas nos meus scripts / ambiente.
#!/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
Isso deve funcionar
echo 00-60-2f-`openssl rand -hex 3 | sed 's/\(..\)/\1-/g; s/.$//'`
end=$( echo $RANDOM | openssl md5 | sed 's/\(..\)/\1-/g' | cut -b-8 )
echo 00-60-2f-$end
Este também funciona. A saída está em letras maiúsculas, conforme necessário.
openssl rand -hex 3 | sed 's/\(..\)\(..\)\(..\)/00-60-2F-\1-\2-\3/' | tr [a-f] [A-F]
Isso funciona no #!/bin/sh
script shell ( ) clássico :
random_mac() {
printf '%.2x\n' "$(shuf -i 0-281474976710655 -n 1)" | sed -r 's/(..)/\1:/g' | cut -d: -f -6
}
Ou, se você deseja 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/(..)/\1:/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
Outra opção é usar jot
:
echo 00-60-2F-$(jot -w%02X -s- -r 3 0 256)
-w
muda o formato, -s
altera o separador e -r
gera números aleatórios.
Os comandos usados od
nas respostas postadas por artistoex e zero2cx adicionam traços extras à saída com OS X od
, mas isso não:
echo 00-60-2f-$(od -tx1 -An -N3 /dev/random|awk '$1=$1'|tr \ -)
OS X od
( /usr/bin/od
abaixo) 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
jot -w%02X -s- -r 3 1 256
para jot -w%02X -s- -r 3 0 256
.
No Linux:
printf '00-60-2f-' && cut -b 7-11,24-26 /proc/sys/kernel/random/uuid
Explicação:
No Linux, /proc/sys/kernel/random/uuid
retorna um novo UUID do tipo 4 (aleatório) toda vez que você o lê. A maioria de seus caracteres é (pseudo) dígitos hexadecimais aleatórios, portanto, podemos usá-los. Por exemplo:
$ cat /proc/sys/kernel/random/uuid
5501ab12-b530-4db5-a8ea-3df93043f172
$ # ^ ^ Beware, these characters are not random.
$ # ^^^^^ ^^^ Let's use characters on these positions.
$ cut -b 7-11,24-26 /proc/sys/kernel/random/uuid
6d-74-a1
$ cut -b 7-11,24-26 /proc/sys/kernel/random/uuid
13-f9-75
Agora basta imprimir 00-60-2f-
(sem nova linha) primeiro:
$ printf '00-60-2f-' && cut -b 7-11,24-26 /proc/sys/kernel/random/uuid
00-60-2f-86-f9-21
Prós:
printf
e cut
são ferramentas POSIX;Contras:
/proc/sys/kernel/random/uuid
pode não estar disponível em alguns sistemas;
echo -n 00-60-2F; dd bs=1 count=3 if=/dev/random 2>/dev/null |hexdump -v -e '/1 "-%02X"'