web-dev-qa-db-ja.com

bashシェルで有効なランダムMACアドレスを生成する方法

どうすればbashで有効なランダムMACアドレスを生成できますか?.

アドレスの前半は常にこのようにしておく必要があります

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

x値だけをランダムに生成する必要がありますか?

18
NES

過去に私はこれを使ってこれをしました:

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」関数に基づいています。この関数は、「フォーマット文字列」を最初のパラメーターとして受け取り、追加のパラメーターがフォーマット文字列に入力します。
  • フォーマット文字列内の%は、「フォーマット指定子」を導入します。これは、引数のフォーマット方法を指示する1つ以上の文字にすることができます。
  • 書式指定子の先行ゼロ(0)は、結果の数値出力に、指定された幅までの先行ゼロを埋め込む必要があることを意味します。
  • 2は、指定子が2文字分の幅を占めて表示されることを示しています。
  • Xは指定子を終了し、数値として解釈され、16進数として表示されることを示します。大文字なので、a〜fの文字は大文字にする必要があります。
  • \ nは改行です。printfは、バックスラッシュをエスケープコードとして解釈し、他の文字、しばしば改行のような扱いにくい文字を表示するために使用できます。
  • フォーマット指定子の残りの文字は文字どおりに出力されます。これには、最初の「00-06-2F-」とフォーマット指定子の間のダッシュが含まれます。
  • 残りの引数はシェル変数の置換($で示される)であり、256を法とする乱数(RANDOM)である数式が含まれます。これにより、0〜255の乱数が生成されます。
17
  1. 次のように適切なサイズのintを生成します。 http://tldp.org/LDP/abs/html/randomvar.html
  2. 次のように16進数に変換します: http://snipplr.com/view/2428/convert-from-int-to-hex/
  3. ランダムに生成された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進数のフィールドのみを使用して16進文字を生成するため、ゼロパディングについて心配する必要はありません。コメントに対処するために修正されたアプローチです。

17
RobotHumans

標準ツールを使用して、

# output in capitals
hexdump -n3 -e'/3 "00-60-2F" 3/1 "-%02X"' /dev/random

または

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

すべての中で最短かもしれません。

13
artistoex
#!/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(タブ)、\n(改行)およびスペースの解釈を無効にします
  • -d ''-改行を許可
  • -r\を許可します(ほとんどの場合、習慣としてreadで使用する必要があります)
  • 形式指定子-%02x\nを指定すると、出力はリテラルハイフンの後に適切な場合は先行ゼロを含む2桁の16進数が続きます。改行はここでは不要なので省略できます。
  • readは、-n 1から0〜255(/dev/urandomFF)の範囲で1バイト(00)を取得します。
  • ループ内のprintfの最後の引数にある単一引用符により、文字が数値として出力されます( "A"は "65"として出力されます)。 POSIX仕様のprintf を参照してください。

    先行文字が単一引用符または二重引用符である場合、値は、単一引用符または二重引用符に続く文字の基礎となるコードセット内の数値です。

私が思いつくことができた最短の方法は、hexdumpを直接使用することでした

echo 00-60-2f$(hexdump -n3 -e '/1 "-%02X"' /dev/random)
  • -n3は、hexdumpに3バイトを読み取るように指示します
  • フォーマット文字列は、各バイトにダッシュと2桁の16進数値を出力します
    • '/ 1'は、すべての読み取りバイトにフォーマットを適用することを意味します
    • 「-%02X」は、先行ゼロ、2桁、大文字の16進値を印刷するためのprintf仕様です
  • / dev/randomはソースのランダムバイトです

GNU/Linuxでテスト済み

7
maxthoursie

別の1行ソリューション

$ echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /-/g'

大文字で同じこと

$ echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /-/g' | tr '[:lower:]' '[:upper:]'

Bash環境変数用に生成します

$ export MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /-/g')
$ echo $MAC

詳細:

  • od(8進ダンプ)

    -An出力の先頭アドレス表現(余分なノイズ)を抑制します。
    -N3出力を3バイトに制限します。
    -t xC 16進数の出力、ASCII文字スタイル、必要に応じて。
    /dev/urandom Linuxカーネル乱数疑似ファイル。

  • sed(ストリームエディター)スペースからハイフンへの置換用。

    -e <SCRIPT> sedスクリプトを実行します。

  • tr(文字列変換)オプション、この例では。私のスクリプト/環境では大文字のMACアドレスが好きです。

4
zero2cx
#!/bin/bash
#Creates an array containing all hexadecimal characters
HEX=(a b c d e f 0 1 2 3 4 5 6 7 8 9)
#Defines MAC string length as 0 (total SL will be 17)
SL=0
#Loop sequentially assigns random hex characters in pairs until a full
#MAC address is generated.
while [ $SL -lt 17 ]
do
        num=`shuf -i 0-15 -n 1` #Generates random number which will be used as array index
        RMAC="$RMAC""${HEX[$num]}" #Uses the randomly generated number to select a hex character
        num=`shuf -i 0-15 -n 1` #New random number
        RMAC="$RMAC""${HEX[$num]}" #Appends second hex character
        SL=$[`echo $RMAC | wc -c` - 1] #Calculates SL and stores in var SL
    if [ $SL -lt 17 ] #If string is uncomplete, appends : character
            then
            RMAC=""$RMAC":"
    fi
done
echo $RMAC #Displays randomly generated MAC address
2
Haematoma

これはうまくいくはずです

echo 00-60-2f-`openssl Rand -hex 3 | sed 's/\(..\)/\1-/g; s/.$//'`
2
linuxrules94
end=$( echo $RANDOM | openssl md5 | sed 's/\(..\)/\1-/g' | cut -b-8 )
echo 00-60-2f-$end
0
Kevin Duterne

これも機能します。必要に応じて、出力はすべて大文字です。

openssl Rand -hex 3 | sed 's/\(..\)\(..\)\(..\)/00-60-2F-\1-\2-\3/' | tr [a-f] [A-F]
0
Jaroslav Kucera

Linuxの場合:

printf '00-60-2f-' && cut -b 7-11,24-26 /proc/sys/kernel/random/uuid

説明:

Linuxでは/proc/sys/kernel/random/uuidは、読み取るたびに新しい type 4(ランダム)UUID を返します。その文字のほとんどは(疑似)ランダムな16進数なので、使用できます。例えば:

$ cat /proc/sys/kernel/random/uuid
5501ab12-b530-4db5-a8ea-3df93043f172
$ #           ^    ^       Beware, these characters are not random.
$ #   ^^^^^            ^^^ Let's use characters on these positions.
$ cut -b 7-11,24-26 /proc/sys/kernel/random/uuid
6d-74-a1
$ cut -b 7-11,24-26 /proc/sys/kernel/random/uuid
13-f9-75

これで、印刷するだけで十分です00-60-2f-(改行なし)最初に:

$ printf '00-60-2f-' && cut -b 7-11,24-26 /proc/sys/kernel/random/uuid
00-60-2f-86-f9-21

長所:

  • 最初からの16進数。変換やフィルタリングは必要ありません。
  • printfおよびcutはPOSIXツールです。
  • (特定の場合)すでにUUIDに含まれているハイフンを使用します。

短所:

  • uUIDの2つのランダムでない数字に注意する必要があります。
  • /proc/sys/kernel/random/uuid一部のシステムでは使用できない場合があります。
  • 小文字だけがとても簡単です(大文字を取得するには追加の手順が必要です)。
0

ワンライナー(バッシュ)

mac=$(c=0;until [ $c -eq "6" ];do printf ":%02X" $(( $RANDOM % 256 ));let c=c+1;done|sed s/://)

結果

$ echo $mac
93:72:71:0B:9E:89
0
Zibri

これはクラシックシェル(#!/bin/sh) 脚本:

random_mac() {
    printf '%.2x\n' "$(shuf -i 0-281474976710655 -n 1)" | sed -r 's/(..)/\1:/g' | cut -d: -f -6
}

または、カスタム接頭辞が必要な場合:

random_mac_with_prefix() {
    echo -n "00:60:2f:" &&
    printf '%.2x\n' "$(shuf -i 0-281474976710655 -n 1)" | sed -r 's/(..)/\1:/g' | cut -d: -f -3
}

使用例:

$ random_mac
96:ef:45:28:45:25
$ random_mac
7e:47:26:ae:ab:d4
$ random_mac_with_prefix 
00:60:2f:24:f4:18
$ random_mac_with_prefix 
00:60:2f:63:08:b2
0
kvaps

もう1つのオプションは、jotを使用することです。

echo 00-60-2F-$(jot -w%02X -s- -r 3 0 256)

-wは形式を変更します、-sはセパレータを変更し、-rは乱数を生成します。

Artistoexおよびzero2cxによって投稿された回答でodを使用するコマンドは、OS Xのodを使用して出力に余分なダッシュを追加しますが、これは次のことを行いません:

echo 00-60-2f-$(od -tx1 -An -N3 /dev/random|awk '$1=$1'|tr \  -)

OS Xのod/usr/bin/od以下)は、GNU odとは異なる出力形式を使用します。

$ /usr/bin/od -N3 -tx1 -An /dev/random|tr ' ' -
-----------c7--fd--55----------------------------------------------------

$ god -N3 -tx1 -An /dev/random|tr ' ' -
-94-9e-5c
0
nisetama