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


16

bashで有効なランダムMACアドレスを生成するにはどうすればよいですか。

アドレスの前半は常にこのように同じままでなければなりません

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

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


10
echo -n 00-60-2F; dd bs=1 count=3 if=/dev/random 2>/dev/null |hexdump -v -e '/1 "-%02X"'
artistoex

1
@artistoexそれは美しかった...なぜあなたは答えとしてそれを投稿しなかったのですか?
bobmagoo

回答:


18

ここに魚がいます。

このシェルスクリプトは、求めるランダムな文字列を生成します。

#!/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

コマンドラインからそれを実行する方法を示したものがここにありましたが、デニス・ウィリアムソンの複雑な(しかし賛成した)ソリューションを見た後、人々が期待する答えは仕事をする必要がないものであることがわかります自分自身。


私は彼が魚の代わりにスプーン送りソリューションをすることを学ぶ作るしようとしていたことを実現するためのおかげで
RobotHumans

1
あなたはどのように約1つのこの時間を提供することに加えて魚指導彼の両方であるように、あなたはいつも...あなたの答えを説明できる
ジェドダニエルズ

このスクリプトは、hbdgafが提案するスクリプトよりもはるかに高速に実行され、1000回のループで無効なMACアドレスを生成しません。ありがとう!
ブルーノフィンガー

1
ソリューションは機能し、3行しかありません。売れました。
リチャードゴメス

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進文字を生成するだけなので、ゼロパディングについて心配する必要はありません。コメントに対処するために修正されたアプローチです。


それぞれの例を提供する場合、余分な+1(私はあなたに彼に釣り方を教えていることは知っていますが、パズルのピースを与えて、組み立てる方法とその理由を説明できます)。
ジェドダニエルズ

@Jed Daniels-完了しました。コードが提供されました。
RobotHumans

このコードは、いくつかの無効なMACを生成しています。それを1000倍をループ私のようないくつかのMACを得ました00-60-2F-8B-5-2C00-60-2F-A-71-9700-60-2F-82-F1-4
ブルーノフィンガー

OPがbashを主張していたので、私はそこに放り出しただけでした。1桁の数字にゼロを埋め込む方法がわからないと言っていますか?@BrunoFinger
RobotHumans

255の代わりに16を使用してゼロプレースホルダーを生成するように簡単に作り直すことができます。それは...ちょうどより多くのラインだ
RobotHumans

16

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

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の乱数が生成されます。

2
以下のようuser58033合法的に(今なくなっているかもしれない)の回答で指摘:%02X1つの大文字を与えるだろう。
アルジャン

ああ、良い点。元の質問が大文字を使用した例を与えたと私は間隔をあけました。歓迎してくれてありがとう。:-)
ショーンレイフシュナイダー

何が起こっているのか、ソリューションが機能する理由を説明できる場合は、+ 1を追加します。
ジェッドダニエルズ


12

標準ツールを使用して、

# 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 \  -)

一番短いかもしれません。


odが正確に何をするかを回答で説明できますか?他の方法でも使用すると便利です!
ブルーノビエリ

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"

これが機能する方法の鍵:

  • LC_CTYPE=C -0x7Fを超える文字を許可
  • IFS=- \t(タブ)、\n(改行)、およびスペースの解釈を無効にします
  • -d ''-改行を許可します
  • -r許可します\(ほぼ常に習慣で使用する必要がありますread
  • 書式指定子-%02x\nにより、出力はリテラルハイフンの後に、必要に応じて先行ゼロを含む2桁の16進数が続きます。改行はここでは不要であり、省略できます。
  • read1バイトを(取得します-n 1から)/dev/urandom(255の範囲で0に00しますFF)。
  • 最後の引数の単一引用符 printfループと、文字が数値として出力されます(「A」は「65」として出力されます)。POSIXの仕様をprintf参照してください:

    先行文字が単一引用符または二重引用符である場合、値は、単一引用符または二重引用符に続く文字の基になるコードセットの数値でなければなりません。


必要に思えるIFS= read …00に09 0Aと20(通常IFSの文字を)折りたたみ避けるために
クリス・ヨンセン

@クリス:申し訳ありませんが、いくつかの二重チェックを行っている間にいくつかのものを取り出し、それらを元に戻すのを忘れました-d ''。答えを修正します。知らせてくれてありがとうございます。
追って通知があるまで一時停止します。

おっと、-r`\`を保護するものが落ちました。シェルプログラムでのバイナリデータの適切な処理がそれほど面倒ではなかったことを願っています。string文字列の途中で00を正確に表すことは不可能のようです。1文字ずつのメソッドは、、read文字列の補間、およびprintf1文字の引数の処理方法の間の便利な(設計された)協力により00を処理します'。はぁ。
クリスジョンセン

@Chris:私のDWIMプロセッサが不安定にならなかったことを望みます。ところで、私が書いた純粋なBashスクリプトがのコア機能を複製しているのに興味があるかもしれませんhexdump -C
追って通知があるまで一時停止します。

何が起こっているのか、ソリューションが機能する理由を説明できる場合は、+ 1を追加します。
ジェッドダニエルズ

7

私が思いついた最短の方法は、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でテスト済み


職場でのUnixの有効性:-)
artistoex

hexdump -n3 -e'/3 "00-60-2F" 3/1 "-%02X"' /dev/random少し短くなります:
artistoex

4

別の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必要に応じて、ASCII文字スタイルの16進数で出力します。
    /dev/urandomLinuxカーネルの乱数擬似ファイル。

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

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

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


2
#!/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

これは動作するはずです

echo 00-60-2f-`openssl rand -hex 3 | sed 's/\(..\)/\1-/g; s/.$//'`


0

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

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

0

これは、クラシックシェル(#!/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

別のオプションは使用することjotです:

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

-wフォーマットを-s変更し、セパレータを変更し、そして-r乱数生成します。

odartistoexとzero2cxによって投稿された回答で使用するコマンドは、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

1
注意してください。この方法で生成された「100」を含むMacがいくつかあります。例:00-60-2F-100-A3-F6
...-ペトルス

@petrusそうですね、答えを編集してに変更jot -w%02X -s- -r 3 1 256しましたjot -w%02X -s- -r 3 0 256
ニセタマ

0

Linuxの場合:

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

説明:

Linuxでは/proc/sys/kernel/random/uuid、読み取るたびに新しいタイプ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およびcutPOSIXツールです。
  • (特定の場合)既にUUIDにあるハイフンは、それらを使用します。

短所:

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

0

ライナー1つ(bash)

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.