Bagaimana saya bisa menghasilkan alamat mac acak yang valid dengan bash.
Paruh pertama dari alamat harus selalu tetap sama seperti ini
00-60-2F-xx-xx-xx
hanya nilai x yang harus dihasilkan secara acak?
Bagaimana saya bisa menghasilkan alamat mac acak yang valid dengan bash.
Paruh pertama dari alamat harus selalu tetap sama seperti ini
00-60-2F-xx-xx-xx
hanya nilai x yang harus dihasilkan secara acak?
Jawaban:
Ini ikan.
Script shell ini akan menghasilkan string acak yang Anda cari:
#!/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
Saya memang punya sesuatu di sini yang menunjukkan cara menjalankannya dari baris perintah, tetapi setelah melihat Dennis Williamson solusi yang berbelit-belit (tapi tervotasikan) saya melihat bahwa jawaban yang orang harapkan adalah jawaban di mana mereka tidak perlu melakukan pekerjaan apa pun diri.
Di masa lalu saya telah melakukan ini menggunakan:
echo 00-60-2F-$[RANDOM%10]$[RANDOM%10]-$[RANDOM%10]$[RANDOM%10]-$[RANDOM%10]$[RANDOM%10]
tapi itu hanya akan membuat mereka berada di kisaran 0-9. Demi tujuan saya, itu sudah cukup baik.
Mungkin solusi yang lebih baik adalah menggunakan printf:
printf '00-60-2F-%02X-%02X-%02X\n' $[RANDOM%256] $[RANDOM%256] $[RANDOM%256]
Begini cara kerjanya:
%02X
akan memberikan satu huruf besar.
#!/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
Atau dengan 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'))
Perhatikan bahwa versi python hanya menggunakan bidang 16 lebar untuk menghasilkan hex char, jadi Anda tidak perlu khawatir tentang nol padding - pendekatan diubah untuk mengatasi komentar.
00-60-2F-8B-5-2C
, 00-60-2F-A-71-97
, 00-60-2F-82-F1-4
.
Menggunakan alat standar, baik
# output in capitals
hexdump -n3 -e'/3 "00-60-2F" 3/1 "-%02X"' /dev/random
atau
# output in lower case letters
echo 00-60-2f$(od -txC -An -N3 /dev/random|tr \ -)
mungkin yang terpendek dari semuanya.
#!/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"
Kunci cara kerjanya:
LC_CTYPE=C
- memungkinkan karakter> 0x7FIFS=
- Menonaktifkan interpretasi \t
(tab), \n
(baris baru) dan ruang-d ''
- memungkinkan baris baru-r
memungkinkan \
(dan harus hampir selalu digunakan oleh kebiasaan dengan read
)-%02x\n
menyebabkan output menjadi tanda hubung literal diikuti oleh bilangan heksadesimal dua digit termasuk nol di depan, jika perlu. Baris baru berlebihan di sini dan bisa dihilangkan.read
mendapat satu byte ( -n 1
) dari /dev/urandom
dalam kisaran 0 sampai 255 ( 00
untuk FF
).Kutipan tunggal dalam argumen terakhir ke printf
dalam loop menyebabkan karakter menjadi output sebagai nilai numeriknya ("A" adalah output sebagai "65"). Lihat spesifikasi POSIX untukprintf
mengatakan:
Jika karakter utama adalah kuotasi tunggal atau kuotasi ganda, nilainya harus berupa nilai numerik dalam kumpulan kode yang mendasari karakter yang mengikuti kuotasi tunggal atau kuotasi ganda.
IFS= read …
untuk menghindari melipat 09 0a dan 20 (karakter IFS biasa) menjadi 00.
-d ''
. Saya akan memperbaiki jawaban saya. Terima kasih telah memberi tahu saya.
-r
yang melindungi `\` rontok. Saya berharap penanganan yang tepat dari data biner dalam program shell tidak terlalu rumit. ☺ Tampaknya mustahil untuk secara akurat mewakili 00 di tengah-tengah string. Metode single-character-at-a-time Anda menangani 00 berdasarkan kerjasama yang nyaman (dirancang?) Antara read
, interpolasi string dan bagaimana printf
memperlakukan argumen satu karakter '
. Mendesah.
hexdump -C
.
Cara terpendek yang bisa saya lakukan adalah menggunakan hexdump secara langsung
echo 00-60-2f$(hexdump -n3 -e '/1 "-%02X"' /dev/random)
Diuji pada GNU / Linux
hexdump -n3 -e'/3 "00-60-2F" 3/1 "-%02X"' /dev/random
sedikit lebih pendek :-)
Solusi satu baris lainnya
$ echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /-/g'
Hal yang sama dalam huruf besar
$ echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /-/g' | tr '[:lower:]' '[:upper:]'
Hasilkan untuk variabel lingkungan Bash
$ export MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /-/g')
$ echo $MAC
Detail:
od (dump oktal)
-An
Menekan representasi alamat utama (noise ekstra) dari output.
-N3
Batasi output hingga tiga byte.
-t xC
Keluaran dalam hex, gaya karakter ASCII, seperti yang diinginkan.
/dev/urandom
Linux pseudo-file kernel angka acak.
sed (stream editor) Untuk ruang pengganti tanda hubung.
-e <SCRIPT>
jalankan skrip sed.
tr (terjemahan string) Opsional, dalam contoh ini. Saya suka alamat MAC huruf besar di skrip / lingkungan saya.
#!/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
Ini seharusnya bekerja
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
Yang ini juga berfungsi. Output semua dalam huruf besar sesuai kebutuhan.
openssl rand -hex 3 | sed 's/\(..\)\(..\)\(..\)/00-60-2F-\1-\2-\3/' | tr [a-f] [A-F]
Ini berfungsi dalam #!/bin/sh
skrip shell ( ) klasik :
random_mac() {
printf '%.2x\n' "$(shuf -i 0-281474976710655 -n 1)" | sed -r 's/(..)/\1:/g' | cut -d: -f -6
}
Atau, jika Anda ingin memiliki awalan khusus:
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
}
Contoh penggunaan:
$ 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
Pilihan lain adalah menggunakan jot
:
echo 00-60-2F-$(jot -w%02X -s- -r 3 0 256)
-w
mengubah format, -s
mengubah pemisah, dan -r
menghasilkan angka acak.
Perintah yang digunakan od
dalam jawaban yang diposting oleh artistoex dan zero2cx menambahkan tanda hubung ekstra ke output dengan OS X's od
, tetapi ini tidak:
echo 00-60-2f-$(od -tx1 -An -N3 /dev/random|awk '$1=$1'|tr \ -)
OS X od
(di /usr/bin/od
bawah) menggunakan format output yang berbeda dari 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
menjadi jot -w%02X -s- -r 3 0 256
.
Di Linux:
printf '00-60-2f-' && cut -b 7-11,24-26 /proc/sys/kernel/random/uuid
Penjelasan:
Di Linux /proc/sys/kernel/random/uuid
mengembalikan yang baru UUID tipe 4 baru (acak) setiap kali Anda membacanya. Sebagian besar karakternya adalah (pseudo) angka heksadesimal acak, sehingga kita dapat menggunakannya. Misalnya:
$ 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
Sekarang sudah cukup untuk mencetak 00-60-2f-
(tanpa baris baru) terlebih dahulu:
$ printf '00-60-2f-' && cut -b 7-11,24-26 /proc/sys/kernel/random/uuid
00-60-2f-86-f9-21
Pro:
printf
dan cut
merupakan alat POSIX;Cons:
/proc/sys/kernel/random/uuid
mungkin tidak tersedia di beberapa sistem;
echo -n 00-60-2F; dd bs=1 count=3 if=/dev/random 2>/dev/null |hexdump -v -e '/1 "-%02X"'