Comment puis-je générer une adresse mac aléatoire valide avec bash.
La première moitié de l'adresse doit toujours rester la même comme celle-ci
00-60-2F-xx-xx-xx
juste la valeur x doit être générée au hasard?
Comment puis-je générer une adresse mac aléatoire valide avec bash.
La première moitié de l'adresse doit toujours rester la même comme celle-ci
00-60-2F-xx-xx-xx
juste la valeur x doit être générée au hasard?
Réponses:
Voici un poisson.
Ce script shell va générer la chaîne aléatoire que vous recherchez:
#!/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
J'avais juste quelque chose ici qui montrait comment l'exécuter à partir de la ligne de commande, mais après avoir regardé la solution compliquée (mais votée) de Dennis Williamson, je vois que la réponse que les gens attendent est celle où ils n'ont pas à faire de travail se.
Dans le passé, je l'ai fait en utilisant:
echo 00-60-2F-$[RANDOM%10]$[RANDOM%10]-$[RANDOM%10]$[RANDOM%10]-$[RANDOM%10]$[RANDOM%10]
mais cela ne les rendra que dans la plage de 0 à 9. Pour mes besoins, c'était assez bon.
Une meilleure solution serait probablement d'utiliser printf:
printf '00-60-2F-%02X-%02X-%02X\n' $[RANDOM%256] $[RANDOM%256] $[RANDOM%256]
Voici comment cela fonctionne:
%02X
donnerait une lettre majuscule.
#!/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 en 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'))
Notez que la version python utilise uniquement un champ large de 16 pour générer un caractère hexadécimal, vous n'avez donc pas à vous soucier du remplissage nul - approche modifiée pour répondre à un commentaire.
00-60-2F-8B-5-2C
, 00-60-2F-A-71-97
, 00-60-2F-82-F1-4
.
À l'aide d'outils standard, soit
# 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 \ -)
pourrait être le plus court de tous.
#!/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"
Les clés du fonctionnement:
LC_CTYPE=C
- autorise les caractères> 0x7FIFS=
- désactive l'interprétation de \t
(tab), \n
(nouvelle ligne) et de l'espace-d ''
- permet les sauts de ligne-r
permet \
(et devrait presque toujours être utilisé par habitude avecread
)-%02x\n
fait que la sortie est un tiret littéral suivi d'un nombre hexadécimal à deux chiffres incluant un zéro de tête, le cas échéant. La nouvelle ligne est superflue ici et pourrait être omise.read
obtient un seul octet ( -n 1
) de /dev/urandom
0 à 255 ( 00
à FF
).Le guillemet simple dans le dernier argument de printf
dans la boucle fait que le caractère est sorti comme sa valeur numérique ("A" est sorti comme "65"). Voir la spécification POSIX pour savoirprintf
où il est indiqué:
Si le premier caractère est un guillemet simple ou un guillemet double, la valeur doit être la valeur numérique dans le jeu de codes sous-jacent du caractère suivant le guillemet simple ou le guillemet double.
IFS= read …
éviter de replier 09 0a et 20 (les caractères IFS habituels) en 00.
-d ''
. Je vais corriger ma réponse. Merci de me le faire savoir.
-r
qui protège `` est tombé. Je souhaite que la bonne gestion des données binaires dans les programmes shell ne soit pas si compliquée. ☺ Il semble impossible de représenter avec précision 00 au milieu de la chaîne. Votre méthode à caractère unique à la fois gère 00 grâce à la coopération pratique (conçue?) Entre read
, l'interpolation de chaînes et la façon dont printf
traite l'argument à un caractère '
. Soupir.
hexdump -C
.
Le moyen le plus court que j'ai pu trouver était d'utiliser directement hexdump
echo 00-60-2f$(hexdump -n3 -e '/1 "-%02X"' /dev/random)
Testé sur GNU / Linux
hexdump -n3 -e'/3 "00-60-2F" 3/1 "-%02X"' /dev/random
est un peu plus court :-)
Une autre solution en ligne
$ echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /-/g'
Même chose en majuscules
$ echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /-/g' | tr '[:lower:]' '[:upper:]'
Générez-le pour une variable d'environnement Bash
$ export MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /-/g')
$ echo $MAC
Détails:
od (vidage octal)
-An
Supprime la principale représentation d'adresse (bruit supplémentaire) de la sortie.
-N3
Limitez la sortie à trois octets.
-t xC
Sortie en hexadécimal, style ASCII, comme vous le souhaitez.
/dev/urandom
Pseudo-fichier à nombres aléatoires du noyau Linux.
sed (éditeur de flux) Pour la substitution d'espace à trait d'union.
-e <SCRIPT>
exécutez le script sed.
tr (traduction de chaîne) Facultatif, dans cet exemple. J'aime les adresses MAC majuscules dans mes scripts / environnement.
#!/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
Cela devrait fonctionner
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
Celui-ci fonctionne également. La sortie est tout en majuscules comme requis.
openssl rand -hex 3 | sed 's/\(..\)\(..\)\(..\)/00-60-2F-\1-\2-\3/' | tr [a-f] [A-F]
Cela fonctionne dans le #!/bin/sh
script shell ( ) classique :
random_mac() {
printf '%.2x\n' "$(shuf -i 0-281474976710655 -n 1)" | sed -r 's/(..)/\1:/g' | cut -d: -f -6
}
Ou, si vous souhaitez avoir un préfixe personnalisé:
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
}
Exemple d'utilisation:
$ 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
Une autre option consiste à utiliser jot
:
echo 00-60-2F-$(jot -w%02X -s- -r 3 0 256)
-w
modifie le format, -s
modifie le séparateur et-r
génère des nombres aléatoires.
Les commandes utilisant od
dans les réponses publiées par artistoex et zero2cx ajoutent des tirets supplémentaires à la sortie avec OS X od
, mais cela ne fait pas:
echo 00-60-2f-$(od -tx1 -An -N3 /dev/random|awk '$1=$1'|tr \ -)
OS X od
( /usr/bin/od
ci-dessous) utilise un format de sortie différent de 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
à jot -w%02X -s- -r 3 0 256
.
Sous Linux:
printf '00-60-2f-' && cut -b 7-11,24-26 /proc/sys/kernel/random/uuid
Explication:
Sous Linux, /proc/sys/kernel/random/uuid
renvoie un nouvel UUID de type 4 (aléatoire) chaque fois que vous le lisez. La plupart de ses caractères sont des chiffres hexadécimaux (pseudo) aléatoires, nous pouvons donc les utiliser. Par exemple:
$ 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
Il suffit maintenant d'imprimer 00-60-2f-
(sans nouvelle ligne) en premier:
$ printf '00-60-2f-' && cut -b 7-11,24-26 /proc/sys/kernel/random/uuid
00-60-2f-86-f9-21
Avantages:
printf
et cut
sont des outils POSIX;Les inconvénients:
/proc/sys/kernel/random/uuid
peut ne pas être disponible sur certains systèmes;
echo -n 00-60-2F; dd bs=1 count=3 if=/dev/random 2>/dev/null |hexdump -v -e '/1 "-%02X"'