Odpowiedzi:
Oto ryba.
Ten skrypt powłoki wygeneruje szukany ciąg losowy:
#!/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
Właśnie miałem tutaj coś, co pokazało, jak uruchomić go z wiersza poleceń, ale po spojrzeniu na skomplikowane (ale uprzywilejowane) rozwiązanie Dennisa Williamsona widzę, że ludzie oczekują odpowiedzi, w której nie muszą wykonywać żadnej pracy sami.
W przeszłości robiłem to za pomocą:
echo 00-60-2F-$[RANDOM%10]$[RANDOM%10]-$[RANDOM%10]$[RANDOM%10]-$[RANDOM%10]$[RANDOM%10]
ale dzięki temu będą tylko w zakresie 0–9. Dla moich celów było to wystarczająco dobre.
Prawdopodobnie lepszym rozwiązaniem byłoby użycie printf:
printf '00-60-2F-%02X-%02X-%02X\n' $[RANDOM%256] $[RANDOM%256] $[RANDOM%256]
Oto jak to działa:
#!/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
Lub w 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'))
Zauważ, że wersja Pythona używa tylko 16-polowego pola do wygenerowania znaku szesnastkowego, więc nie musisz się martwić o zerowanie dopełniania - poprawiono podejście, aby odpowiedzieć na komentarz.
00-60-2F-8B-5-2C
, 00-60-2F-A-71-97
, 00-60-2F-82-F1-4
.
Za pomocą standardowych narzędzi
# output in capitals
hexdump -n3 -e'/3 "00-60-2F" 3/1 "-%02X"' /dev/random
lub
# output in lower case letters
echo 00-60-2f$(od -txC -An -N3 /dev/random|tr \ -)
może być najkrótszy ze wszystkich.
#!/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"
Klucze do sposobu, w jaki to działa:
LC_CTYPE=C
- zezwala na znaki> 0x7FIFS=
- wyłącza interpretację \t
(tab), \n
(nowa linia) i spacji-d ''
- pozwala na nowe linie-r
pozwala \
(i prawie zawsze powinien być używany przez nawyk z read
)-%02x\n
powoduje, że wyjście jest dosłownym łącznikiem, po którym następuje dwucyfrowa liczba szesnastkowa, w razie potrzeby z wiodącym zerem. Nowa linia jest tutaj zbędna i można ją pominąć.read
Dostaje jeden bajt ( -n 1
) z /dev/urandom
zakresu od 0 do 255 ( 00
z FF
).Pojedynczy cudzysłów w ostatnim argumencie do printf
pętli powoduje, że znak jest wyprowadzany jako jego wartość liczbowa („A” jest wyprowadzane jako „65”). Zobacz specyfikację POSIX,printf
gdzie jest napisane:
Jeżeli wiodącym znakiem jest pojedynczy cudzysłów lub podwójny cudzysłów, wartością jest wartość liczbowa w podstawowym zestawie znaków znaku następującego po pojedynczym cudzysłowie lub podwójnym cudzysłowie.
IFS= read …
unikać składania 09 0a i 20 (zwykłe znaki IFS) do 00.
-d ''
. Naprawię moją odpowiedź. Dzięki, że dałeś mi znać.
-r
który chroni `\` wypadł. Chciałbym, aby właściwe przetwarzanie danych binarnych w programach powłoki nie było tak skomplikowane. Seems Wydaje się niemożliwe dokładne odwzorowanie 00 na środku łańcucha. Twoja metoda jednoznakowa na raz obsługuje 00 dzięki wygodnej (zaprojektowanej?) Współpracy między read
interpolacją ciągów znaków i printf
traktowaniu argumentu jednoznakowego '
. Westchnienie.
hexdump -C
.
Najkrótszym sposobem, jaki mogłem wymyślić, było użycie zrzutu heksadecymalnego bezpośrednio
echo 00-60-2f$(hexdump -n3 -e '/1 "-%02X"' /dev/random)
Testowany na GNU / Linux
hexdump -n3 -e'/3 "00-60-2F" 3/1 "-%02X"' /dev/random
jest nieco krótszy :-)
Kolejne rozwiązanie jednoliniowe
$ echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /-/g'
To samo wielkie litery
$ echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /-/g' | tr '[:lower:]' '[:upper:]'
Wygeneruj go dla zmiennej środowiskowej Bash
$ export MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /-/g')
$ echo $MAC
Detale:
od (ósemkowy zrzut)
-An
Pomija wiodącą reprezentację adresu (dodatkowy szum) na wyjściu.
-N3
Ogranicz dane wyjściowe do trzech bajtów.
-t xC
Dane wyjściowe w postaci szesnastkowej, ASCII, zgodnie z życzeniem.
/dev/urandom
Pseudo-plik jądra systemu Linux.
sed (edytor strumieniowy) Dla podstawienia spacją do łącznika.
-e <SCRIPT>
wykonać skrypt sed.
tr (tłumaczenie napisów) Opcjonalne, w tym przykładzie. W moich skryptach / środowisku lubię duże adresy MAC.
#!/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
To powinno działać
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
Ten też działa. W razie potrzeby dane wyjściowe są pisane wielkimi literami.
openssl rand -hex 3 | sed 's/\(..\)\(..\)\(..\)/00-60-2F-\1-\2-\3/' | tr [a-f] [A-F]
Działa to w klasycznym #!/bin/sh
skrypcie shell ( ):
random_mac() {
printf '%.2x\n' "$(shuf -i 0-281474976710655 -n 1)" | sed -r 's/(..)/\1:/g' | cut -d: -f -6
}
Lub jeśli chcesz mieć niestandardowy prefiks:
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
}
Przykładowe użycie:
$ 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
Inną opcją jest użycie jot
:
echo 00-60-2F-$(jot -w%02X -s- -r 3 0 256)
-w
zmienia format, -s
zmienia separator i -r
generuje liczby losowe.
Polecenia użyte od
w odpowiedziach opublikowanych przez artistoex i zero2cx dodają dodatkowe myślniki do danych wyjściowych w OS X od
, ale to nie:
echo 00-60-2f-$(od -tx1 -An -N3 /dev/random|awk '$1=$1'|tr \ -)
OS X od
( /usr/bin/od
poniżej) używa innego formatu wyjściowego niż 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
na jot -w%02X -s- -r 3 0 256
.
W systemie Linux:
printf '00-60-2f-' && cut -b 7-11,24-26 /proc/sys/kernel/random/uuid
Wyjaśnienie:
W systemie Linux /proc/sys/kernel/random/uuid
zwraca nowy UUID typu 4 (losowy) za każdym razem, gdy go czytasz. Większość jego znaków to (pseudo) losowe cyfry szesnastkowe, więc możemy ich użyć. Na przykład:
$ 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
Teraz wystarczy 00-60-2f-
najpierw wydrukować (bez nowej linii):
$ printf '00-60-2f-' && cut -b 7-11,24-26 /proc/sys/kernel/random/uuid
00-60-2f-86-f9-21
Plusy:
printf
i cut
są narzędziami POSIX;Cons:
/proc/sys/kernel/random/uuid
może nie być dostępny w niektórych systemach;
echo -n 00-60-2F; dd bs=1 count=3 if=/dev/random 2>/dev/null |hexdump -v -e '/1 "-%02X"'