有一个mac地址,我只需要用一个不同的随机数(必须与原始字符不同)替换一个十六进制字符(一个在非常特定的位置)。我已经使用xxd以这种方式完成了工作,并且有效:
from ctypes import windll
user32 = windll.user32
user32.SetProcessDPIAware()
我的脚本的问题是使用#!/bin/bash
mac="00:00:00:00:00:00" #This is a PoC mac address obviously :)
different_mac_digit=$(xxd -p -u -l 100 < /dev/urandom | sed "s/${mac:10:1}//g" | head -c 1)
changed_mac=${mac::10}${different_mac_digit}${mac:11:6}
echo "${changed_mac}" #This echo stuff like 00:00:00:0F:00:00
意味着另一个依赖...我想避免使用它(并非所有Linux默认都包含它)。我使用xxd
命令对此有另一种解决方法,但是使用它却处于同一阶段...但是我的脚本已经具有强制性的hexdump
依赖性,所以...可以使用{ {1}}?我需要一个awk
管理员:)谢谢。
答案 0 :(得分:2)
类似的事情可能适用于$RANDOM
中的种子值:
mac="00:00:00:00:00:00"
awk -v seed=$RANDOM 'BEGIN{ FS=OFS=":"; srand(seed) } {
s="0"
while ((s = sprintf("%x", rand() * 16)) == substr($4, 2, 1))
$4 = substr($4, 1, 1) s
} 1' <<< "$mac"
00:00:00:03:00:00
在while循环内,我们继续进行直到十六进制数字不等于substr($4, 2, 1)
的第四列的第二个字符。
答案 1 :(得分:1)
bash内置有printf和一个随机函数(如果您信任的话):
different_mac_digit() {
new=$1
while [[ $new = $1 ]]; do
new=$( printf "%X" $(( RANDOM%16 )) )
done
echo $new
}
调用要替换的字符作为参数。
答案 2 :(得分:1)
您不需要xxd
或hexdump
。 urandom
还将生成与用于表示十六进制数字的数字和字母的编码相匹配的数字,因此您可以使用
old="${mac:10:1}"
different_mac_digit=$(tr -dc 0-9A-F < /dev/urandom | tr -d "$old" | head -c1)
当然,您也可以将整个脚本替换为awk
脚本。以下GNU awk
脚本将用与旧行不同的随机十六进制符号替换每行的第11个符号。使用<<< macaddress
,我们可以将macaddress
馈送到其stdin,而不必使用echo
或类似的东西。
awk 'BEGIN { srand(); pos=11 } {
old=strtonum("0x" substr($0,pos,1))
new=(old + 1 + int(rand()*15)) % 16
print substr($0,1,pos-1) sprintf("%X",new) substr($0,pos+1)
}' <<< 00:00:00:00:00:00
此处的窍门是在要修改的数字上添加1到15之间的一个随机数(包括两者)。如果最后得到的数字大于15,则使用模运算符%
(16
变为0
,17
变为1
,然后以此类推)。这样一来,就可以保证所得数字与旧数字不同。
但是,如果完全用bash编写,则相同的方法会更短。
mac="00:00:00:00:00:00"
old="${mac:10:1}"
(( new=(16#"$old" + 1 + RANDOM % 15) % 16 ))
printf %s%X%s\\n "${mac::10}" "$new" "${mac:11}"
“单线”版本:
mac=00:00:00:00:00:00
printf %s%X%s\\n "${mac::10}" "$(((16#${mac:10:1}+1+RANDOM%15)%16))" "${mac:11}"
答案 3 :(得分:1)
另一个awk:
$ awk -v n=11 -v s=$RANDOM ' # set n to char # you want to replace
BEGIN { FS=OFS="" }{ # each char is a field
srand(s)
while((r=sprintf("%x",rand()*16))==$n);
$n=r
}1' <<< $mac
输出:
00:00:00:07:00:00
或oneliner:
$ awk -v n=11 -v s=$RANDOM 'BEGIN{FS=OFS=""}{srand(s);while((r=sprintf("%x",rand()*16))==$n);$n=r}1' <<< $mac
答案 4 :(得分:1)
$ mac="00:00:00:00:00:00"
$ awk -v m="$mac" -v p=11 'BEGIN{srand(); printf "%s%X%s\n", substr(m,1,p-1), int(rand()*15-1), substr(m,p+1)}'
00:00:00:01:00:00
$ awk -v m="$mac" -v p=11 'BEGIN{srand(); printf "%s%X%s\n", substr(m,1,p-1), int(rand()*15-1), substr(m,p+1)}'
00:00:00:0D:00:00
并确保您获得的数字与开始时的数字不同:
$ awk -v mac="$mac" -v pos=11 'BEGIN {
srand()
new = old = toupper(substr(mac,pos,1))
while (new==old) {
new = sprintf("%X", int(rand()*15-1))
}
print substr(mac,1,pos-1) new substr(mac,pos+1)
}'
00:00:00:0D:00:00