如何使用 bash shell 生成有效的随机 MAC 地址

如何使用 bash shell 生成有效的随机 MAC 地址

如何使用 bash 生成有效的随机 mac 地址。

地址的前半部分应该始终保持不变,如下所示

00-60-2F-xx-xx-xx

只是 x 值应该是随机生成的?

答案1

过去我曾使用过以下方法完成此操作:

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]

工作原理如下:

  • printf 程序基于 C“printf”函数,该函数以“格式字符串”作为第一个参数,然后以附加参数填充格式字符串。
  • 格式字符串中的 % 引入了一个“格式说明符”,它可以是一个或多个字符,用于指示如何格式化参数。
  • 格式说明符中的前导零 (0) 表示应在生成的数字输出中用前导零填充至指定的宽度。
  • 2 表示说明符应占用两个字符的宽度进行显示。
  • X 结束说明符,表示应将其解释为数字并以十六进制显示。由于它是大写的,因此字母 af 也应大写。
  • \n 是换行符——printf 将反斜杠解释为转义码,可用于显示其他字符,通常是换行符等棘手的字符。
  • 格式说明符中的其余字符将按原样打印出来,其中包括开头的“00-06-2F-”和格式说明符之间的破折号。
  • 其余参数是 shell 变量替换(用 $ 表示),并包含一个数学表达式,该表达式是一个模 256 的随机数(RANDOM)。这会产生一个介于 0 和 255 之间的随机数。

答案2

这里有一条鱼。

这个 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

我确实在这里展示了如何从命令行运行它,但是在看了 Dennis Williamson 复杂但被赞成的)解决方案后,我发现人们期望的答案是他们不需要自己做任何工作的答案。

答案3

  1. 生成适当大小的整数,如下所示:http://tldp.org/LDP/abs/html/randomvar.html
  2. 像这样转换为十六进制:http://snipplr.com/view/2428/convert-from-int-to-hex/
  3. 在三个随机生成的块之间添加破折号
#!/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 宽的字段来生成十六进制字符,因此您不必担心零填充 - 方法已修改以解决注释。

答案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- 允许字符 > 0x7F

  • IFS=\t- 禁用(tab)、\n(换行) 和空格的解释

  • -d ''- 允许换行

  • -r允许\(并且应该几乎总是习惯性地与 一起使用read

  • 格式说明符-%02x\n使输出为文字连字符,后跟两位十六进制数(如果合适,包括前导零)。此处的换行符是多余的,可以省略。

  • 获取范围为 0 到 255(到)内的read单个字节(-n 1)。/dev/urandom00FF

  • 循环中最后一个参数中的单引号printf使字符输出为其数值(“A”输出为“65”)。请参阅POSIX 规范printf其中写道:

    如果前导字符是单引号或双引号,则该值应为单引号或双引号后字符的底层代码集中的数值。

相关内容