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

NES*_*NES 18 bash mac-address

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

地址的前半部分应始终保持不变

00-60-2F-xx-xx-xx
Run Code Online (Sandbox Code Playgroud)

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

del*_*ray 19

这里有一条鱼。

此 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
Run Code Online (Sandbox Code Playgroud)

我确实只是在这里展示了如何从命令行运行它,但是在查看了 Dennis Williamson 令人费解(但赞成)的解决方案后,我看到人们期望的答案是他们不必做任何工作的答案他们自己。


Sea*_*der 19

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

echo 00-60-2F-$[RANDOM%10]$[RANDOM%10]-$[RANDOM%10]$[RANDOM%10]-$[RANDOM%10]$[RANDOM%10]
Run Code Online (Sandbox Code Playgroud)

但这只会使它们在 0-9 范围内。就我的目的而言,这已经足够了。

可能更好的解决方案是使用 printf:

printf '00-60-2F-%02X-%02X-%02X\n' $[RANDOM%256] $[RANDOM%256] $[RANDOM%256]
Run Code Online (Sandbox Code Playgroud)

这是它的工作原理:

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

  • 正如 [user58033](http://superuser.com/users/58033/user58033) 在答案中正确指出的那样(现在可能已经消失了):`%02X` 将给出一个大写字母。 (2认同)

Rob*_*ans 17

  1. 像这样生成适当大小的 int: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
Run Code Online (Sandbox Code Playgroud)

或者在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'))
Run Code Online (Sandbox Code Playgroud)

请注意,python 版本仅使用 16 宽字段来生成十六进制字符,因此您不必担心零填充 - 已修改方法以解决注释。


wnr*_*rph 14

使用标准工具,或者

# output in capitals
hexdump -n3 -e'/3 "00-60-2F" 3/1 "-%02X"' /dev/random
Run Code Online (Sandbox Code Playgroud)

或者

# output in lower case letters
echo 00-60-2f$(od -txC -An -N3 /dev/random|tr \  -)
Run Code Online (Sandbox Code Playgroud)

可能是最短的。


Den*_*son 7

#!/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"
Run Code Online (Sandbox Code Playgroud)

其工作方式的关键:

  • LC_CTYPE=C - 允许字符 > 0x7F

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

  • -d ''- 允许换行

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

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

  • read得到一个单一的字节(-n 1从)/dev/urandom中的范围为0〜255(00FF)。

  • printfin 循环的最后一个参数中的单引号导致字符作为其数值输出(“A”输出为“65”)。请参阅POSIX 规范以了解printf其内容:

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


小智 7

我能想到的最短方法是直接使用 hexdump

echo 00-60-2f$(hexdump -n3 -e '/1 "-%02X"' /dev/random)
Run Code Online (Sandbox Code Playgroud)
  • -n3 告诉 hexdump 读取三个字节
  • 格式字符串为每个字节打印一个破折号和一个两位数的十六进制值
    • '/1' 表示为每个读取字节应用格式
    • “-%02X”是用于打印前导零、两位数、大写十六进制值的 printf 规范
  • /dev/random 是源随机字节

在 GNU/Linux 上测试