Respuestas:
Aquí hay un pez.
Este script de shell generará la cadena aleatoria que busca:
#!/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
Acabo de tener algo aquí que mostró cómo ejecutarlo desde la línea de comandos, pero después de mirar a Dennis Williamson una solución enrevesada (pero votada) veo que la respuesta que la gente espera es aquella en la que no tienen que hacer ningún trabajo sí mismos.
En el pasado hice esto usando:
echo 00-60-2F-$[RANDOM%10]$[RANDOM%10]-$[RANDOM%10]$[RANDOM%10]-$[RANDOM%10]$[RANDOM%10]
pero eso solo los hará en el rango 0-9. Para mis propósitos, eso fue lo suficientemente bueno.
Probablemente una mejor solución sería usar printf:
printf '00-60-2F-%02X-%02X-%02X\n' $[RANDOM%256] $[RANDOM%256] $[RANDOM%256]
Así es como funciona:
#!/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 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'))
Tenga en cuenta que la versión de Python solo usa un campo de 16 de ancho para generar un carácter hexadecimal, por lo que no tiene que preocuparse por el relleno cero: enfoque modificado para abordar un comentario.
00-60-2F-8B-5-2C
, 00-60-2F-A-71-97
, 00-60-2F-82-F1-4
.
Usando herramientas estándar, ya sea
# 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 \ -)
podría ser el más corto 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"
Las claves de la forma en que esto funciona:
LC_CTYPE=C
- permite caracteres> 0x7FIFS=
- desactiva la interpretación de \t
(tab), \n
(nueva línea) y espacio-d ''
- permite nuevas líneas-r
permite \
(y casi siempre debe usarse por hábito con read
)-%02x\n
hace que la salida sea un guión literal seguido de un número hexadecimal de dos dígitos que incluye un cero inicial, si corresponde. La nueva línea es superflua aquí y podría omitirse.read
consigue un solo byte ( -n 1
) a partir de /dev/urandom
en el rango de 0 a 255 ( 00
a FF
).La comilla simple en el último argumento printf
en el bucle hace que el carácter se muestre como su valor numérico ("A" se muestra como "65"). Consulte la especificación POSIX para saberprintf
dónde dice:
Si el carácter inicial es una comilla simple o una comilla doble, el valor será el valor numérico en el conjunto de códigos subyacente del carácter que sigue a la comilla simple o la comilla doble.
IFS= read …
evitarse doblar 09 0a y 20 (los caracteres IFS habituales) en 00.
-d ''
. Arreglaré mi respuesta. Gracias por hacérmelo saber.
-r
cayó el que protege `\`. Desearía que el manejo adecuado de los datos binarios en los programas de shell no fuera tan complicado. ☺ Parece imposible representar con precisión 00 en el medio de la cadena. Su método de un solo carácter a la vez maneja 00 en virtud de la cooperación conveniente (¿diseñada?) Entre la read
interpolación de cadenas y cómo printf
trata el argumento de un carácter '
. Suspiro.
hexdump -C
.
La forma más corta que pude encontrar fue usando hexdump directamente
echo 00-60-2f$(hexdump -n3 -e '/1 "-%02X"' /dev/random)
Probado en GNU / Linux
hexdump -n3 -e'/3 "00-60-2F" 3/1 "-%02X"' /dev/random
es un poco más corto :-)
Otra solución de una línea
$ echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /-/g'
Lo mismo en mayúsculas
$ echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /-/g' | tr '[:lower:]' '[:upper:]'
Generarlo para una variable de entorno Bash
$ export MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /-/g')
$ echo $MAC
Detalles:
od (volcado octal)
-An
Suprime la representación de dirección principal (ruido adicional) de la salida.
-N3
Limite la salida a tres bytes.
-t xC
Salida en hexadecimal, estilo de caracteres ASCII, según se desee.
/dev/urandom
Pseudoarchivo de números aleatorios del kernel de Linux.
sed (editor de flujo) Para la sustitución de espacios con guiones.
-e <SCRIPT>
ejecuta el script sed.
tr (traducción de cadena) Opcional, en este ejemplo. Me gustan las direcciones MAC mayúsculas en mis scripts / entorno.
#!/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
Esto debería 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 también funciona. La salida es todo en mayúsculas según sea necesario.
openssl rand -hex 3 | sed 's/\(..\)\(..\)\(..\)/00-60-2F-\1-\2-\3/' | tr [a-f] [A-F]
Esto funciona en el #!/bin/sh
script clásico de shell ( ):
random_mac() {
printf '%.2x\n' "$(shuf -i 0-281474976710655 -n 1)" | sed -r 's/(..)/\1:/g' | cut -d: -f -6
}
O, si quieres tener un prefijo 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
}
Ejemplo 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
Otra opción es usar jot
:
echo 00-60-2F-$(jot -w%02X -s- -r 3 0 256)
-w
cambia el formato, -s
cambia el separador y -r
genera números aleatorios.
Los comandos que se utilizan od
en las respuestas publicadas por artistoex y zero2cx agregan guiones adicionales a la salida con OS X od
, pero esto no:
echo 00-60-2f-$(od -tx1 -An -N3 /dev/random|awk '$1=$1'|tr \ -)
OS X od
( /usr/bin/od
abajo) usa un formato de salida diferente al 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
a jot -w%02X -s- -r 3 0 256
.
En Linux:
printf '00-60-2f-' && cut -b 7-11,24-26 /proc/sys/kernel/random/uuid
Explicación:
En Linux /proc/sys/kernel/random/uuid
devuelve un nuevo UUID de tipo 4 (aleatorio) cada vez que lo lee. La mayoría de sus caracteres son dígitos hexadecimales (pseudo) aleatorios, por lo que podemos usarlos. P.ej:
$ 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
Ahora es suficiente imprimir 00-60-2f-
(sin nueva línea) primero:
$ printf '00-60-2f-' && cut -b 7-11,24-26 /proc/sys/kernel/random/uuid
00-60-2f-86-f9-21
Pros:
printf
y cut
son herramientas POSIX;Contras:
/proc/sys/kernel/random/uuid
puede no estar disponible en algunos sistemas;
echo -n 00-60-2F; dd bs=1 count=3 if=/dev/random 2>/dev/null |hexdump -v -e '/1 "-%02X"'