Antworten:
Hier ist ein Fisch.
Dieses Shell-Skript generiert die zufällige Zeichenfolge, die Sie suchen:
#!/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
Ich hatte hier nur etwas, das zeigte, wie man es von der Kommandozeile aus ausführt, aber nach einem Blick auf Dennis Williamsons komplizierte (aber hochgeladene) Lösung sehe ich, dass die Antwort, die die Leute erwarten, die ist, bei der sie keine Arbeit erledigen müssen sich.
#!/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
Oder in 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'))
Beachten Sie, dass die Python-Version nur ein 16-faches Feld zum Generieren eines Hex-Zeichens verwendet, sodass Sie sich keine Gedanken über das Null-Auffüllen machen müssen - Ansatz geändert, um einen Kommentar zu adressieren.
00-60-2F-8B-5-2C
, 00-60-2F-A-71-97
, 00-60-2F-82-F1-4
.
In der Vergangenheit habe ich folgendes getan:
echo 00-60-2F-$[RANDOM%10]$[RANDOM%10]-$[RANDOM%10]$[RANDOM%10]-$[RANDOM%10]$[RANDOM%10]
aber das wird sie nur im Bereich von 0-9 machen. Für meine Zwecke war das gut genug.
Eine wahrscheinlich bessere Lösung wäre die Verwendung von printf:
printf '00-60-2F-%02X-%02X-%02X\n' $[RANDOM%256] $[RANDOM%256] $[RANDOM%256]
So funktioniert das:
Auch mit Standardwerkzeugen
# output in capitals
hexdump -n3 -e'/3 "00-60-2F" 3/1 "-%02X"' /dev/random
oder
# output in lower case letters
echo 00-60-2f$(od -txC -An -N3 /dev/random|tr \ -)
könnte die kürzeste von allen sein.
#!/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"
Die Schlüssel zur Funktionsweise:
LC_CTYPE=C
- erlaubt Zeichen> 0x7FIFS=
- Deaktiviert die Interpretation von \t
(Tab), \n
(Newline) und Leerzeichen-d ''
- erlaubt Zeilenumbrüche-r
erlaubt \
(und sollte fast immer aus Gewohnheit verwendet werden read
)-%02x\n
bewirkt, dass die Ausgabe ein literaler Bindestrich gefolgt von einer zweistelligen Hexadezimalzahl und gegebenenfalls einer führenden Null ist. Die Newline ist hier überflüssig und könnte weggelassen werden.read
ein einzelnes Byte ( -n 1
) /dev/urandom
im Bereich von 0 bis 255 ( 00
bis FF
).Das einfache Anführungszeichen im letzten Argument printf
der Schleife bewirkt, dass das Zeichen als numerischer Wert ausgegeben wird ("A" wird als "65" ausgegeben). In der POSIX-Spezifikationprintf
steht:
Wenn das führende Zeichen ein einfaches Anführungszeichen oder ein doppeltes Anführungszeichen ist, ist der Wert der numerische Wert im zugrunde liegenden Codesatz des Zeichens nach dem einfachen Anführungszeichen oder dem doppelten Anführungszeichen.
IFS= read …
vermeiden, 09 0a und 20 (die üblichen IFS-Zeichen) in 00 zu folden.
-d ''
. Ich werde meine Antwort reparieren. Danke für die Information.
-r
, was "\" schützt, ist rausgefallen. Ich wünschte, der richtige Umgang mit Binärdaten in Shell-Programmen wäre nicht so kompliziert. ☺ Es scheint unmöglich zu sein, 00 in der Mitte der Zeichenfolge genau darzustellen. Ihre Einzelzeichenmethode verarbeitet 00 aufgrund der praktischen (entworfenen?) Zusammenarbeit zwischen der read
Zeichenfolgeninterpolation und der printf
Behandlung des Ein-Zeichen-Arguments '
. Seufzer.
hexdump -C
.
Der kürzeste Weg, den ich finden konnte, war die direkte Verwendung von Hexdump
echo 00-60-2f$(hexdump -n3 -e '/1 "-%02X"' /dev/random)
Getestet unter GNU / Linux
hexdump -n3 -e'/3 "00-60-2F" 3/1 "-%02X"' /dev/random
ist etwas kürzer :-)
Eine andere einzeilige Lösung
$ echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /-/g'
Gleiches in Großbuchstaben
$ echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /-/g' | tr '[:lower:]' '[:upper:]'
Generieren Sie es für eine Bash-Umgebungsvariable
$ export MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /-/g')
$ echo $MAC
Einzelheiten:
od (Oktaldump)
-An
Unterdrückt die führende Adressendarstellung (zusätzliches Rauschen) der Ausgabe.
-N3
Begrenzen Sie die Ausgabe auf drei Bytes.
-t xC
Ausgabe wahlweise in hexadezimaler ASCII-Schreibweise.
/dev/urandom
Linux-Kernel-Zufallszahlen-Pseudodatei.
sed (Stream-Editor) Für Leerzeichen zum Ersetzen von Bindestrichen.
-e <SCRIPT>
Führen Sie das sed-Skript aus.
tr (Stringübersetzung) Optional in diesem Beispiel. Ich mag MAC-Adressen in Großbuchstaben in meinen Skripten / meiner Umgebung.
#!/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
Das sollte funktionieren
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
Dieser funktioniert auch. Die Ausgabe erfolgt nach Bedarf in Großbuchstaben.
openssl rand -hex 3 | sed 's/\(..\)\(..\)\(..\)/00-60-2F-\1-\2-\3/' | tr [a-f] [A-F]
Dies funktioniert im klassischen shell ( #!/bin/sh
) Skript:
random_mac() {
printf '%.2x\n' "$(shuf -i 0-281474976710655 -n 1)" | sed -r 's/(..)/\1:/g' | cut -d: -f -6
}
Oder, wenn Sie ein benutzerdefiniertes Präfix haben möchten:
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
}
Anwendungsbeispiel:
$ 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
Eine andere Option ist die Verwendung von jot
:
echo 00-60-2F-$(jot -w%02X -s- -r 3 0 256)
-w
ändert das Format, -s
ändert das Trennzeichen und-r
generiert Zufallszahlen.
Die Befehle, die od
in den von artistoex und zero2cx geposteten Antworten verwendet werden, fügen der Ausgabe unter OS X zusätzliche Gedankenstriche hinzu od
, was jedoch nicht der Fall ist:
echo 00-60-2f-$(od -tx1 -An -N3 /dev/random|awk '$1=$1'|tr \ -)
OS X od
( /usr/bin/od
unten) verwendet ein anderes Ausgabeformat als 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
zu 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
Erläuterung:
Unter Linux wird bei jedem Lesen /proc/sys/kernel/random/uuid
eine neue UUID vom Typ 4 (zufällig) zurückgegeben . Die meisten seiner Zeichen sind (pseudo) zufällige hexadezimale Ziffern, daher können wir sie verwenden. Z.B:
$ 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
Jetzt genügt es, zuerst 00-60-2f-
(ohne Zeilenvorschub) zu drucken :
$ printf '00-60-2f-' && cut -b 7-11,24-26 /proc/sys/kernel/random/uuid
00-60-2f-86-f9-21
Vorteile:
printf
und cut
sind POSIX-Tools;Nachteile:
/proc/sys/kernel/random/uuid
ist auf einigen Systemen möglicherweise nicht verfügbar;
echo -n 00-60-2F; dd bs=1 count=3 if=/dev/random 2>/dev/null |hexdump -v -e '/1 "-%02X"'