我如何使用bash生成有效的随机mac地址。
地址的前半部分应始终像这样保持不变
00-60-2F-xx-xx-xx
只是x值应该随机生成?
我如何使用bash生成有效的随机mac地址。
地址的前半部分应始终像这样保持不变
00-60-2F-xx-xx-xx
只是x值应该随机生成?
Answers:
这是一条鱼。
该shell脚本将生成您要查找的随机字符串:
#!/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
我只是在这里展示了如何从命令行运行它的内容,但是在看了丹尼斯·威廉姆森令人费解(但被否决)的解决方案之后,我看到人们期望的答案是他们不必做任何工作的答案他们自己。
过去,我使用以下方法完成此操作:
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]
运作方式如下:
%02X
将给出一个大写字母。
#!/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
或在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'))
请注意,python版本仅使用16个宽域来生成十六进制字符,因此您不必担心零填充-修改方法可解决注释。
00-60-2F-8B-5-2C
,00-60-2F-A-71-97
,00-60-2F-82-F1-4
。
#!/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
得到一个单一的字节(-n 1
从)/dev/urandom
中的范围为0〜255(00
至FF
)。printf
循环中最后一个参数中的单引号引起字符以其数值输出(“ A”输出为“ 65”)。请参阅POSIX规范printf
中的说明:
如果前导字符是单引号或双引号,则该值应是单引号或双引号后面字符的基础代码集中的数值。
IFS= read …
避免折叠09 0A和20(通常的IFS字符)转换成00
-d ''
。我会解决我的答案。谢谢你让我知道。
-r
保护`\`的掉了。我希望在shell程序中正确处理二进制数据不是那么麻烦。seems似乎无法在字符串中间准确表示00。您一次的单字符方法通过read
字符串插值以及如何printf
处理单字符参数之间的便捷(设计的)协作来处理00 '
。叹。
我想出的最短方法是直接使用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
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]
这是经典shell(#!/bin/sh
)脚本中的工作方式:
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 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
返回一个新的类型4(随机)的UUID。它的大多数字符都是(伪)随机十六进制数字,因此我们可以使用它们。例如:
$ 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
在某些系统上可能不可用;
echo -n 00-60-2F; dd bs=1 count=3 if=/dev/random 2>/dev/null |hexdump -v -e '/1 "-%02X"'