ฉันจะสร้างที่อยู่ mac แบบสุ่มที่ถูกต้องด้วย bash ได้อย่างไร
ครึ่งแรกของที่อยู่ควรเหมือนกันเสมอ
00-60-2F-xx-xx-xx
ค่า x ควรถูกสร้างแบบสุ่ม?
ฉันจะสร้างที่อยู่ mac แบบสุ่มที่ถูกต้องด้วย bash ได้อย่างไร
ครึ่งแรกของที่อยู่ควรเหมือนกันเสมอ
00-60-2F-xx-xx-xx
ค่า x ควรถูกสร้างแบบสุ่ม?
คำตอบ:
นี่คือปลา
เชลล์สคริปต์นี้จะสร้างสตริงสุ่มที่คุณค้นหา:
#!/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
ฉันเพิ่งมีบางอย่างที่นี่ซึ่งแสดงวิธีเรียกใช้จากบรรทัดคำสั่ง แต่หลังจากดูวิธีแก้ปัญหาที่ซับซ้อน (แต่ upvoted) ของ Dennis Williamson ฉันเห็นว่าคำตอบที่คนคาดหวังคือสิ่งที่พวกเขาไม่ต้องทำงานใด ๆ ตัวเอง
ในอดีตที่ผ่านมาฉันได้ทำสิ่งนี้โดยใช้:
echo 00-60-2F-$[RANDOM%10]$[RANDOM%10]-$[RANDOM%10]$[RANDOM%10]-$[RANDOM%10]$[RANDOM%10]
แต่นั่นจะทำให้พวกเขาอยู่ในช่วง 0-9 เท่านั้น สำหรับวัตถุประสงค์ของฉันนั่นก็ดีพอ
อาจเป็นทางออกที่ดีกว่าคือการใช้ printf:
printf '00-60-2F-%02X-%02X-%02X\n' $[RANDOM%256] $[RANDOM%256] $[RANDOM%256]
นี่คือวิธีการทำงาน:
#!/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
หรือในไพ ธ อน:
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'))
โปรดทราบว่าเวอร์ชันของไพ ธ อนใช้ฟิลด์ที่มีความกว้างเพียง 16 เพื่อสร้าง hex char ดังนั้นคุณไม่ต้องกังวลเกี่ยวกับการเติมเต็มศูนย์ - วิธีการแก้ไขเพื่อแก้ไขความคิดเห็น
00-60-2F-8B-5-2C
, ,00-60-2F-A-71-97
00-60-2F-82-F1-4
ใช้เครื่องมือมาตรฐานอย่างใดอย่างหนึ่ง
# output in capitals
hexdump -n3 -e'/3 "00-60-2F" 3/1 "-%02X"' /dev/random
หรือ
# output in lower case letters
echo 00-60-2f$(od -txC -An -N3 /dev/random|tr \ -)
อาจจะสั้นที่สุดของทั้งหมด
#!/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"
กุญแจสู่การทำงาน:
LC_CTYPE=C
- อนุญาตให้ใช้อักขระ> 0x7FIFS=
- ปิดใช้การตีความของ\t
(แท็บ), \n
(ขึ้นบรรทัดใหม่) และช่องว่าง-d ''
- อนุญาตการขึ้นบรรทัดใหม่-r
อนุญาต\
(และควรใช้กับการติดนิสัยread
)-%02x\n
ทำให้เอาต์พุตเป็นเครื่องหมายยัติภังค์ตามตัวอักษรตามด้วยเลขฐานสิบหกสองหลักรวมถึงศูนย์นำถ้าเหมาะสม ขึ้นบรรทัดใหม่ที่นี่ไม่จำเป็นและอาจถูกละเว้นread
รับ byte เดียว ( -n 1
) จาก/dev/urandom
ในช่วง 0-255 ( 00
เพื่อFF
)เครื่องหมายคำพูดเดี่ยวในอาร์กิวเมนต์สุดท้ายprintf
ของลูปทำให้ตัวอักขระเป็นเอาต์พุตเป็นค่าตัวเลข ("A" คือเอาต์พุตเป็น "65") ดูข้อกำหนด POSIX สำหรับprintf
ที่ระบุว่า:
ถ้าอักขระนำหน้าเป็นเครื่องหมายคำพูดเดี่ยวหรือเครื่องหมายคำพูดคู่ค่าจะเป็นค่าตัวเลขในชุดโค้ดพื้นฐานของอักขระตามเครื่องหมายคำพูดเดี่ยวหรือเครื่องหมายคำพูดคู่
IFS= read …
หลีกเลี่ยงการพับ 09 0a และ 20 (ตัวอักษร IFS ปกติ) เป็น 00
-d ''
ขออภัยผมเอาสองสิ่งที่ออกมาจากการตรวจสอบในขณะที่ทำคู่บางและลืมที่จะนำพวกเขากลับมาอยู่ในนอกจากนี้ยังมีความต้องการ. ฉันจะแก้ไขคำตอบของฉัน ขอบคุณสำหรับการให้ฉันรู้ว่า.
-r
ที่ปกป้อง `` หลุดออกมา ฉันต้องการการจัดการข้อมูลไบนารีที่เหมาะสมในโปรแกรมเชลล์ไม่ได้เล่นแร่แปรธาตุ ☺ดูเหมือนเป็นไปไม่ได้ที่จะเป็นตัวแทนอย่างถูกต้อง 00 ในช่วงกลางของสตริง คุณตัวเดียว-at-เวลาวิธีการจับ 00 โดยอาศัยอำนาจตามความสะดวก (ออกแบบ?) ความร่วมมือระหว่างread
สายการแก้ไขและวิธีการปฏิบัติอาร์กิวเมนต์หนึ่งตัวอักษรprintf
'
ถอนหายใจ
hexdump -C
ที่ผมเขียนว่าซ้ำกันฟังก์ชั่นหลักของ
วิธีที่สั้นที่สุดที่ฉันสามารถทำได้คือใช้ hexdump โดยตรง
echo 00-60-2f$(hexdump -n3 -e '/1 "-%02X"' /dev/random)
ทดสอบบน GNU / Linux
hexdump -n3 -e'/3 "00-60-2F" 3/1 "-%02X"' /dev/random
สั้นกว่าเล็กน้อย :-)
อีกโซลูชันหนึ่งบรรทัด
$ echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /-/g'
สิ่งเดียวกันในกรณีบน
$ echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /-/g' | tr '[:lower:]' '[:upper:]'
สร้างขึ้นสำหรับตัวแปรสภาพแวดล้อม Bash
$ export MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /-/g')
$ echo $MAC
รายละเอียด:
od (ฐานแปด)
-An
ไม่แสดงการแสดงที่อยู่ (เสียงรบกวนพิเศษ) ของเอาต์พุต
-N3
จำกัด ผลลัพธ์ที่สามไบต์
-t xC
เอาต์พุตในรูปแบบอักขระฐานสิบหก, ASCII ตามต้องการ
/dev/urandom
เคอร์เนล pseudo-สุ่มหมายเลขเคอร์เนลของ Linux
sed (สตรีมเอดิเตอร์) สำหรับพื้นที่ว่างเพื่อทดแทนการใช้เครื่องหมายขีดกลาง
-e <SCRIPT>
รันสคริปต์ sed
tr (การแปลสตริง) เป็นทางเลือกในตัวอย่างนี้ ฉันชอบที่อยู่ 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
สิ่งนี้น่าจะใช้ได้
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
อันนี้ใช้ได้ดีเช่นกัน เอาต์พุตจะเป็นตัวพิมพ์ใหญ่ทั้งหมดตามต้องการ
openssl rand -hex 3 | sed 's/\(..\)\(..\)\(..\)/00-60-2F-\1-\2-\3/' | tr [a-f] [A-F]
สิ่งนี้ทำงานใน#!/bin/sh
สคริปต์classic shell ( ):
random_mac() {
printf '%.2x\n' "$(shuf -i 0-281474976710655 -n 1)" | sed -r 's/(..)/\1:/g' | cut -d: -f -6
}
หรือถ้าคุณต้องการมีคำนำหน้ากำหนดเอง:
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
}
ตัวอย่างการใช้งาน:
$ 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
ตัวเลือกอื่นคือการใช้jot
:
echo 00-60-2F-$(jot -w%02X -s- -r 3 0 256)
-w
เปลี่ยนรูปแบบ -s
เปลี่ยนตัวคั่นและ-r
สร้างตัวเลขสุ่ม
คำสั่งที่ใช้od
ในคำตอบที่โพสต์โดย artistoex และ zero2cx เพิ่มเครื่องหมายขีดคั่นพิเศษไปยังเอาต์พุตด้วย OS X od
แต่ไม่ได้:
echo 00-60-2f-$(od -tx1 -An -N3 /dev/random|awk '$1=$1'|tr \ -)
OS X's od
( /usr/bin/od
ด้านล่าง) ใช้รูปแบบผลลัพธ์ที่แตกต่างจาก 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
ใน Linux:
printf '00-60-2f-' && cut -b 7-11,24-26 /proc/sys/kernel/random/uuid
คำอธิบาย:
ใน Linux /proc/sys/kernel/random/uuid
จะส่งคืนUUID ชนิดที่ 4 (สุ่ม) ใหม่ทุกครั้งที่คุณอ่าน ตัวละครส่วนใหญ่เป็นเลขฐานสิบหกแบบสุ่ม (หลอก) ดังนั้นเราสามารถใช้มันได้ เช่น:
$ 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
ตอนนี้ก็เพียงพอที่จะพิมพ์00-60-2f-
(โดยไม่ขึ้นบรรทัดใหม่) ก่อน:
$ printf '00-60-2f-' && cut -b 7-11,24-26 /proc/sys/kernel/random/uuid
00-60-2f-86-f9-21
ข้อดี:
printf
และcut
เป็นเครื่องมือ POSIX;จุดด้อย:
/proc/sys/kernel/random/uuid
อาจไม่สามารถใช้ได้ในบางระบบหนึ่งซับ (ทุบตี)
mac=$(c=0;until [ $c -eq "6" ];do printf ":%02X" $(( $RANDOM % 256 ));let c=c+1;done|sed s/://)
ผลลัพธ์
$ echo $mac
93:72:71:0B:9E:89
echo -n 00-60-2F; dd bs=1 count=3 if=/dev/random 2>/dev/null |hexdump -v -e '/1 "-%02X"'