Bash kabuğu ile geçerli bir rasgele MAC adresi nasıl oluşturulur


17

Nasıl bash ile geçerli bir rastgele mac adresi oluşturabilirim.

Adresin ilk yarısı her zaman böyle kalmalı

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

sadece x değeri rastgele oluşturulmalı mı?


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 Çok güzeldi ... Bunu neden cevap olarak göndermedin?
bobmagoo

Yanıtlar:


18

İşte bir balık.

Bu kabuk betiği aradığınız rastgele dizeyi oluşturur:

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

Burada sadece komut satırından nasıl çalıştırılacağını gösteren bir şeyim vardı, ancak Dennis Williamson kıvrımlı (ancak yükseltilmiş) çözümlere baktıktan sonra insanların bekledikleri cevabın herhangi bir iş yapmak zorunda kalmadıkları cevap olduğunu görüyorum. kendilerini.


onu bir çözümle kaşıkla beslemek yerine balık
tutmayı

1
Cevabınızı her zaman açıklayabilirsiniz, böylece ikiniz de ona bu sefer bir tane
vermenin

Bu komut dosyası, hbdgaf tarafından önerilen koddan çok daha hızlı çalışır ve 1000 kez döngüde herhangi bir geçersiz MAC adresi oluşturmaz. Teşekkürler!
Bruno Finger

1
Çözümünüz çalışıyor ve sadece 3 satır var. Satıldım.
Richard Gomes

17

Geçmişte bunu kullanarak yaptım:

echo 00-60-2F-$[RANDOM%10]$[RANDOM%10]-$[RANDOM%10]$[RANDOM%10]-$[RANDOM%10]$[RANDOM%10]

ancak bu onları yalnızca 0-9 aralığında yapar. Benim amacım için bu yeterince iyiydi.

Muhtemelen daha iyi bir çözüm printf kullanmak olacaktır:

printf '00-60-2F-%02X-%02X-%02X\n' $[RANDOM%256] $[RANDOM%256] $[RANDOM%256]

Bunun nasıl çalıştığı aşağıda açıklanmıştır:

  • Printf programı, ilk parametre olarak bir "biçim dizesi" alan C "printf" işlevini temel alır ve daha sonra biçim dizesini ek parametreler doldurur.
  • Biçim dizesindeki%, bağımsız değişkenlerin nasıl biçimlendirileceğini anlatan bir veya daha fazla karakter olabilen bir "biçim belirteci" sunar.
  • Biçim belirleyicisindeki baştaki sıfır (0), sonuçta elde edilen sayısal çıktının belirtilen genişliğe kadar baştaki sıfırlarla doldurulması gerektiği anlamına gelir.
  • 2, belirtecin iki karakter genişliğinde olacak şekilde görüntülenmesi gerektiğini söylüyor.
  • X, belirteci bitirir ve bir sayı olarak yorumlanması ve onaltılık sayı olarak gösterilmesi gerektiğini belirtir. Büyük harf olduğundan, af harfleri büyük harf olmalıdır.
  • \ N bir yeni satırdır - printf, ters eğik çizgiyi diğer satırları (genellikle satırsonu gibi zor karakterleri) görüntülemek için kullanılabilen bir çıkış kodu olarak yorumlar.
  • Biçim belirticisindeki kalan karakterler kelimenin tam anlamıyla yazdırılır, buna ilk "00-06-2F-" ve biçim belirleyicileri arasındaki tire işaretleri dahildir.
  • Kalan argümanlar kabuk değişkeni ikameleridir ($ ile gösterilir) ve rastgele bir sayı (RANDOM) modulo 256 olan bir matematik ifadesi içerir. Bu, 0 ile 255 arasında rastgele bir sayı ile sonuçlanır.

2
User58033 bir cevapta haklı olarak işaret ettiği gibi ( şimdi gidebilir ): %02Xbir büyük harf verir.
Arjan

Ah, iyi bir noktaya değindin. Orijinal sorunun büyük harf kullanarak bir örnek verdiğini belirttim. Karşılama için teşekkürler. :-)
Sean Reifschneider

Neler olduğunu ve çözümünüzün neden çalıştığını açıklayabiliyorsanız ekstra +1.
Jed Daniels

İşte böyle, @Jed.
Sean Reifschneider

17
  1. Şu şekilde uygun boyutlu bir int oluşturun: http://tldp.org/LDP/abs/html/randomvar.html
  2. Şu şekilde onaltılık biçime dönüştürün: http://snipplr.com/view/2428/convert-from-int-to-hex/
  3. Rastgele oluşturulmuş üç parça arasına tire ekleyin
#!/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

Veya python'da:

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 sürümünün yalnızca onaltılık bir karakter oluşturmak için 16 genişlik bir alan kullandığını unutmayın, bu nedenle sıfır doldurma konusunda endişelenmenize gerek yoktur - bir yorumu ele almak için değiştirilmiş yaklaşım.


Her birine bir örnek verirseniz ekstra +1 (Ona balık tutmayı öğrettiğinizi biliyorum, ama bir araya getirmek ve nasıl / neden çalıştıklarını açıklamak için bulmacanın parçalarını verebilirsiniz).
Jed Daniels

@Jed Daniels - bitti ve bitti. kod sağlandı.
RobotHumans

Bu kod benim için birkaç geçersiz MAC oluşturuyor. O 1000 kez Döngü gibi birkaç Mac'ler var 00-60-2F-8B-5-2C, 00-60-2F-A-71-97, 00-60-2F-82-F1-4.
Bruno Finger

OP bash üzerinde ısrar ettiği için oraya attığım bir şeydi. Tek basamakları sıfır ile nasıl dolduracağınızı anlayamayacağınızı mı söylüyorsunuz? @BrunoFinger
RobotHumans

255 yerine 16 kullanmak ve sıfır yer tutucu oluşturmak için kolayca yeniden çalışılabilir. Daha fazla satır ...
RobotHumans

12

Standart araçları kullanarak

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

veya

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

en kısa olabilir.


Cevabınızda od'un tam olarak ne yaptığını anlatabilir misiniz? Başka şekillerde de kullanmanıza yardımcı olur!
Bruno Bieri

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"

Bunun çalışma şeklinin anahtarları:

  • LC_CTYPE=C - 0x7F karakterlerine izin verir
  • IFS=- \t(sekme), \n(satırsonu) ve alanın yorumlanmasını devre dışı bırakır
  • -d ''- yeni satırlara izin verir
  • -rizin verir \(ve neredeyse her zaman alışkanlık tarafından kullanılmalıdır read)
  • Biçim belirleyicisi -%02x\n, çıktının değişmez bir kısa çizgi ve ardından uygunsa, başında sıfır içeren iki basamaklı onaltılık bir sayı olmasını sağlar. Newline burada gereksiz ve ihmal edilebilir.
  • readTek bir bayt (alır -n 1itibaren) /dev/urandom0 ila 255 (içinde 00için FF).
  • printfDöngüdeki son bağımsız değişkende yer alan tek tırnak , karakterin sayısal değeri olarak çıkmasına neden olur ("A", "65" olarak çıkar). Yazdığı yerprintf için POSIX spesifikasyonuna bakın :

    Baştaki karakter tek tırnak veya çift tırnak ise, değer tek tırnak veya çift tırnaktan sonraki karakterin temel kod kümesindeki sayısal değer olmalıdır.


IFS= read …09 0a ve 20'yi (her zamanki IFS karakterlerini) 00'a katlamaktan kaçınması gerekiyor gibi görünüyor.
Chris Johnsen

@Chris: Özür dilerim, çifte kontrol yaparken birkaç şeyi çıkardım ve geri koymayı unuttum -d ''. Cevabımı düzeltirim. Bana bildirdiğiniz için teşekkürler.
sonraki duyuruya kadar duraklatıldı.

Hata, -rkoruyan `` düştü. Keşke kabuk programlarında ikili verinin düzgün işlenmesini o kadar da zor değildi. ☺ Dizenin ortasında 00'ı doğru bir şekilde temsil etmek imkansız görünüyor. Tek seferde tek karakterli yönteminiz read, dize enterpolasyonu ve printftek karakterli argümanın nasıl ele alındığı arasındaki uygun (tasarlanmış?) İşbirliği sayesinde 00'ı işler '. İç çekmek.
Chris Johnsen

@Chris: Keşke DWIM işlemcim fritz'de olmasaydı. Bu arada, yazdığım saf bir Bash betiğini görmek isteyebilirsiniz hexdump -C.
sonraki duyuruya kadar duraklatıldı.

Neler olduğunu ve çözümünüzün neden çalıştığını açıklayabiliyorsanız ekstra +1.
Jed Daniels

7

Gelebildiğim en kısa yol doğrudan hexdump kullanmaktı

echo 00-60-2f$(hexdump -n3 -e '/1 "-%02X"' /dev/random)
  • -n3, hexdump'a üç bayt okumasını söyler
  • Biçim dizesi, her bayt için bir tire ve iki basamaklı onaltılık bir değer yazdırır
    • '/ 1', her okunan bayt için biçim uygulama anlamına gelir
    • "-% 02X" baştaki sıfır, iki basamaklı, büyük harf onaltılık değer yazdırmak için bir printf spesifikasyonudur
  • / dev / random, rastgele bir bayt kaynağıdır

GNU / Linux üzerinde test edildi


İşyerinde Unix etkinliği :-)
artistoex

hexdump -n3 -e'/3 "00-60-2F" 3/1 "-%02X"' /dev/randombiraz daha kısa :-)
artistoex

4

Başka bir tek çözüm

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

Büyük harfle aynı şey

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

Bash ortam değişkeni için üret

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

Detaylar:

  • od (sekizli dökümü)

    -AnÇıktının önde gelen adres gösterimini (ekstra gürültü) bastırır.
    -N3Çıkışı üç bayt ile sınırlayın.
    -t xCÇıktı, istendiği gibi onaltılık, ASCII karakter stilinde.
    /dev/urandomLinux çekirdek rasgele sayı sözde dosya.

  • sed (akış düzenleyici) Tire ile yer değiştirme için alan.

    -e <SCRIPT> sed komut dosyasını yürütün.

  • tr (dize çevirisi) Bu örnekte isteğe bağlı. Komut dosyalarımda / ortamımda büyük MAC adreslerini seviyorum.


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

Bu çalışmalı

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

0
end=$( echo $RANDOM | openssl md5 | sed 's/\(..\)/\1-/g' | cut -b-8 )
echo 00-60-2f-$end

5
Neler olduğunu ve çözümünüzün neden çalıştığını açıklayabiliyorsanız ekstra +1.
Jed Daniels

0

Bu da işe yarıyor. Çıktının tamamı gerektiği gibi büyük harflidir.

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

0

Bu klasik shell ( #!/bin/sh) betiğinde çalışır:

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

Veya, özel önek istiyorsanız:

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
}

Örnek kullanım:

$ 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

Başka bir seçenek kullanmaktır jot:

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

-wbiçimi -sdeğiştirir, ayırıcıyı değiştirir ve -rrasgele sayılar üretir.

odArtistoex ve zero2cx tarafından gönderilen cevaplarda kullanılan komutlar , OS X'lerle çıktıya ekstra tire eklerod , ancak bu yapmaz:

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

OS X'ler od( /usr/bin/odaşağıda) GNU'dan farklı bir çıktı biçimi kullanır od:

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

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

1
Not ile sakının. Onlara "100" olması bu şekilde oluşturulan bazı mac, mesela 00-60-2F-100-A3-F6 var ...
petrus

@petrus Haklısınız, ben değişime cevabını düzenlenebilir konum jot -w%02X -s- -r 3 1 256için jot -w%02X -s- -r 3 0 256.
nisetama

0

Linux'ta:

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

Açıklama:

Linux'ta her okuduğunuzda /proc/sys/kernel/random/uuidyeni bir tip 4 (rastgele) UUID döndürür . Karakterlerinin çoğu (sözde) rastgele onaltılık sayılardır, böylece bunları kullanabiliriz. Örneğin:

$ 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

Şimdi önce 00-60-2f-(satırsonu olmadan) yazdırmak yeterlidir :

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

Artıları:

  • en başından onaltılık basamaklar, dönüşüm / filtreleme gerekmez;
  • printfve cutPOSIX araçlarıdır;
  • (özel durumunuz için) zaten UUID'de bulunan tire işaretleri kullanırız.

Eksileri:

  • UUID'deki rastgele olmayan iki basamağı dikkate almamız gerekir;
  • /proc/sys/kernel/random/uuid bazı sistemlerde bulunmayabilir;
  • sadece küçük harfler çok kolay gelir (büyük harfleri almak için ek bir adım gerekir).

0

Bir astar (bash)

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

sonuç

$ echo $mac
93:72:71:0B:9E:89
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.