Come posso generare un indirizzo Mac casuale valido con bash.
La prima metà dell'indirizzo dovrebbe rimanere sempre la stessa
00-60-2F-xx-xx-xx
solo il valore x dovrebbe essere generato casualmente?
Come posso generare un indirizzo Mac casuale valido con bash.
La prima metà dell'indirizzo dovrebbe rimanere sempre la stessa
00-60-2F-xx-xx-xx
solo il valore x dovrebbe essere generato casualmente?
Risposte:
Ecco un pesce
Questo script di shell genererà la stringa casuale che cerchi:
#!/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
Avevo solo qualcosa qui che mostrava come eseguirlo dalla riga di comando, ma dopo aver visto la soluzione contorta (ma migliorata) di Dennis Williamson, vedo che la risposta che la gente si aspetta è quella in cui non è necessario svolgere alcun lavoro loro stessi.
In passato l'ho fatto usando:
echo 00-60-2F-$[RANDOM%10]$[RANDOM%10]-$[RANDOM%10]$[RANDOM%10]-$[RANDOM%10]$[RANDOM%10]
ma questo li renderà solo nell'intervallo 0-9. Per i miei scopi, era abbastanza buono.
Probabilmente una soluzione migliore sarebbe usare printf:
printf '00-60-2F-%02X-%02X-%02X\n' $[RANDOM%256] $[RANDOM%256] $[RANDOM%256]
Ecco come funziona:
#!/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
O in pitone:
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'))
Nota che la versione di Python utilizza solo un campo largo 16 per generare un carattere esadecimale, quindi non devi preoccuparti di zero padding - approccio modificato per indirizzare un commento.
00-60-2F-8B-5-2C
, 00-60-2F-A-71-97
, 00-60-2F-82-F1-4
.
Utilizzando anche strumenti standard
# output in capitals
hexdump -n3 -e'/3 "00-60-2F" 3/1 "-%02X"' /dev/random
o
# output in lower case letters
echo 00-60-2f$(od -txC -An -N3 /dev/random|tr \ -)
potrebbe essere il più breve di tutti.
#!/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"
Le chiavi del modo in cui funziona:
LC_CTYPE=C
- consente caratteri> 0x7FIFS=
- disabilita l'interpretazione di \t
(tab), \n
(newline) e spazio-d ''
- consente newline-r
consente \
(e dovrebbe quasi sempre essere utilizzato per abitudine con read
)-%02x\n
fa sì che l'output sia un trattino letterale seguito da un numero esadecimale a due cifre incluso uno zero iniziale, se appropriato. La newline è superflua qui e potrebbe essere omessa.read
ottiene un singolo byte ( -n 1
) dal /dev/urandom
nell'intervallo da 0 a 255 ( 00
a FF
).La virgoletta singola nell'ultimo argomento printf
nel ciclo provoca l'output del carattere come valore numerico ("A" viene emesso come "65"). Vedi le specifiche POSIX perprintf
dove dice:
Se il carattere principale è una virgoletta singola o una virgoletta doppia, il valore deve essere il valore numerico nel set di codici sottostante del carattere che segue la virgoletta singola o la virgoletta doppia.
IFS= read …
evitare di piegare 09 0a e 20 (i soliti caratteri IFS) in 00.
-d ''
. Riparerò la mia risposta. Grazie per avermi fatto sapere.
-r
che protegge `` è caduto fuori. Vorrei che la corretta gestione dei dati binari nei programmi shell non fosse così complicata. ☺ Sembra impossibile rappresentare con precisione 00 nel mezzo della stringa. Il tuo metodo a carattere singolo alla volta gestisce 00 in virtù della comoda (progettata?) Cooperazione tra l' read
interpolazione di stringhe e il modo in cui printf
tratta l'argomento di un carattere '
. Sospiro.
hexdump -C
.
Il modo più breve che potevo trovare era usare direttamente hexdump
echo 00-60-2f$(hexdump -n3 -e '/1 "-%02X"' /dev/random)
Testato su GNU / Linux
hexdump -n3 -e'/3 "00-60-2F" 3/1 "-%02X"' /dev/random
è un po 'più breve :-)
Un'altra soluzione a una riga
$ echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /-/g'
Stessa cosa in maiuscolo
$ echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /-/g' | tr '[:lower:]' '[:upper:]'
Generalo per una variabile d'ambiente Bash
$ export MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /-/g')
$ echo $MAC
Dettagli:
od (discarica ottale)
-An
Elimina la rappresentazione dell'indirizzo principale (rumore extra) dell'output.
-N3
Limitare l'output a tre byte.
-t xC
Uscita in esadecimale, stile di carattere ASCII, come desiderato.
/dev/urandom
Pseudo-file con numero casuale del kernel Linux.
sed (stream editor) Per lo spazio alla sostituzione del trattino.
-e <SCRIPT>
eseguire lo script sed.
tr (traduzione stringa) Facoltativo, in questo esempio. Mi piacciono gli indirizzi MAC maiuscoli nei miei script / 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
Questo dovrebbe funzionare
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
Anche questo funziona. L'output è tutto in maiuscolo come richiesto.
openssl rand -hex 3 | sed 's/\(..\)\(..\)\(..\)/00-60-2F-\1-\2-\3/' | tr [a-f] [A-F]
Funziona con il classico #!/bin/sh
script shell ( ):
random_mac() {
printf '%.2x\n' "$(shuf -i 0-281474976710655 -n 1)" | sed -r 's/(..)/\1:/g' | cut -d: -f -6
}
Oppure, se si desidera avere un prefisso personalizzato:
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
}
Esempio di utilizzo:
$ 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
Un'altra opzione è utilizzare jot
:
echo 00-60-2F-$(jot -w%02X -s- -r 3 0 256)
-w
cambia il formato, -s
cambia il separatore e-r
genera numeri casuali.
I comandi che usano od
nelle risposte postate da artistoex e zero2cx aggiungono trattini extra all'output con OS X od
, ma questo non:
echo 00-60-2f-$(od -tx1 -An -N3 /dev/random|awk '$1=$1'|tr \ -)
OS X od
( /usr/bin/od
sotto) utilizza un formato di output diverso da 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
a jot -w%02X -s- -r 3 0 256
.
In Linux:
printf '00-60-2f-' && cut -b 7-11,24-26 /proc/sys/kernel/random/uuid
Spiegazione:
In Linux /proc/sys/kernel/random/uuid
restituisce un nuovo UUID di tipo 4 (casuale) ogni volta che lo leggi. La maggior parte dei suoi personaggi sono cifre esadecimali (pseudo) casuali, quindi possiamo usarle. Per esempio:
$ 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
Ora è sufficiente stampare prima 00-60-2f-
(senza riga nuova):
$ printf '00-60-2f-' && cut -b 7-11,24-26 /proc/sys/kernel/random/uuid
00-60-2f-86-f9-21
Professionisti:
printf
e cut
sono strumenti POSIX;Contro:
/proc/sys/kernel/random/uuid
potrebbe non essere disponibile su alcuni sistemi;
echo -n 00-60-2F; dd bs=1 count=3 if=/dev/random 2>/dev/null |hexdump -v -e '/1 "-%02X"'