have a mac address and I need to replace only one hex char (one at a very specific position) by a different random one (it must be different than the original). I have it done in this way using xxd and it works:
#!/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
The problem for my script is that using xxd
means another dependency... I want to avoid it (not all Linux have it included by default). I have another workaround for this using hexdump
command but using it I'm at the same stage... But my script already has a mandatory awk
dependency, so... Can this be done using awk
? I need an awk
master here :) Thanks.
You don't need xxd
or hexdump
. urandom
will also generate nubmers that match the encodings of the digits and letters used to represent hexadecimal numbers, therefore you can just use
old="${mac:10:1}"
different_mac_digit=$(tr -dc 0-9A-F < /dev/urandom | tr -d "$old" | head -c1)
Of course, you can replace your whole script with an awk
script too. The following GNU awk
script will replace the 11th symbol of each line with a random hexadecimal symbol different from the old one. With <<< macaddress
we can feed macaddress
to its stdin without having to use echo
or something like that.
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
The trick here is to add a random number between 1 and 15 (both inclusive) to the digit to be modified. If we end up with a number greater than 15 we wrap around using the modulo operator %
(16
becomes 0
, 17
becomes 1
, and so on). That way the resulting digit is guaranteed to be different from the old one.
However, the same approach would be shorter if written completely in 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}"
"One-liner" version:
mac=00:00:00:00:00:00
printf %s%X%s\\n "${mac::10}" "$(((16#${mac:10:1}+1+RANDOM%15)%16))" "${mac:11}"