How to generate a valid random MAC Address with bash shell
How can i generate a valid random mac adress with bash.
The first half of the adress should always stay same like this
00-60-2F-xx-xx-xx
just the x value should be generated random?
Solution 1:
In the past I've done this using:
echo 00-60-2F-$[RANDOM%10]$[RANDOM%10]-$[RANDOM%10]$[RANDOM%10]-$[RANDOM%10]$[RANDOM%10]
but that will only make them in the range 0-9. For my purposes, that was good enough.
Probably a better solution would be to use printf:
printf '00-60-2F-%02X-%02X-%02X\n' $[RANDOM%256] $[RANDOM%256] $[RANDOM%256]
Here's how that works:
- The printf program is based on the C "printf" function, which takes a "format string" as the first parameter and then additional parameters fill in the format string.
- % in the format string introduces a "format specifier" which can be one or more characters telling how to format the arguments.
- A leading zero (0) in a format specifier means that the resulting numeric output should be padded with leading zeros up to the specified width.
- The 2 says that the specifier should be displayed taking up two characters worth of width.
- The X ends the specifier and denotes that it should be interpreted as a number and displayed as hexidecimal. Because it's upper-case, the letters a-f should be upper case.
- The \n is a newline -- printf interprets backslash as an escape code which can be used to display other characters, often tricky characters like the newline.
- The remaining characters in the format specifier are printed out literally, this includes the initial "00-06-2F-" and the dashes between the format specifiers.
- The remaining arguments are shell variable substitutions (denoted by the $) and include a math expression which is a random number (RANDOM) modulo 256. This results in a random number between 0 and 255.
Solution 2:
Here is a fish.
This shell script will generate the random string you seek:
#!/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
I did just have something here that showed how to run it from the command line, but after looking at Dennis Williamson convoluted (but upvoted) solution I see that the answer that people expect is the one where they don't have to do any work themselves.
Solution 3:
- Generate an appropriately sized int like so: http://tldp.org/LDP/abs/html/randomvar.html
- Convert to hex like so: http://snipplr.com/view/2428/convert-from-int-to-hex/
- Add the dashes between three randomly generated chunks
#!/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
Or in 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'))
Note that the python version only uses a 16 wide field to generate a hex char, so you don't have to worry about zero padding - approach amended to address a comment.