bash 셸을 사용하여 유효한 임의의 MAC 주소를 생성하는 방법


17

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

여기에 커맨드 라인에서 실행하는 방법을 보여주는 무언가가 있었지만 Dennis Williamson의 복잡한 솔루션을 살펴본 후에 사람들이 기대하는 대답은 그들이 할 일이없는 대답이라는 것을 알았습니다. 그들 자신.


내가 그를 만들려고 노력하는 것을 실현하기위한 감사 대신 숟가락 먹이 솔루션의 낚시하는 법을 배워야
RobotHumans

1
당신은 항상 당신에게 대답을 설명 할 수 있습니다 당신은 둘 다 이번에 주위에 하나를 제공하는 것 외에도 낚시하는 법을 가르치고 있습니다 ...
Jed Daniels

이 스크립트는 hbdgaf가 제안한 것보다 훨씬 빠르게 실행되며 1000 회 루프에서 유효하지 않은 MAC 주소를 생성하지 않습니다. 감사!
Bruno Finger

1
솔루션이 작동하고 3 줄만 있습니다. 나는 팔렸다.
Richard Gomes

17

과거에는 다음을 사용 하여이 작업을 수행했습니다.

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"함수를 기반으로합니다.이 함수는 "형식 문자열"을 첫 번째 매개 변수로 사용하고 추가 매개 변수는 형식 문자열을 채 웁니다.
  • 형식화 문자열에 %는 인수 형식화 방법을 알려주는 하나 이상의 문자 일 수있는 "형식 지정자"를 소개합니다.
  • 형식 지정자에서 선행 0은 결과 숫자 출력이 지정된 폭까지 선행 0으로 채워 져야 함을 의미합니다.
  • 2는 지정자가 너비에 해당하는 두 문자를 차지하도록 표시되어야한다고 말합니다.
  • X는 지정자를 끝내고 숫자로 해석되고 16 진수로 표시되어야 함을 나타냅니다. 대문자이므로 문자 af는 대문자 여야합니다.
  • \ n은 줄 바꿈입니다. printf는 백 슬래시를 이스케이프 코드로 해석하여 다른 문자를 표시하는 데 사용할 수 있습니다.
  • 형식 지정자의 나머지 문자는 문자 그대로 인쇄되며 여기에는 초기 "00-06-2F-"및 형식 지정자 사이의 대시가 포함됩니다.
  • 나머지 인수는 쉘 변수 대체 ($로 표시)이며 난수 (RANDOM) 모듈로 256 인 수학 표현식을 포함합니다. 이로 인해 0과 255 사이의 난수가 발생합니다.

2
으로 user58033 정당 (지금은 없어 질 수 있음)에 대한 답변에서 지적 : %02X하나의 대문자를 줄 것이다.
Arjan

아, 좋은 지적입니다. 나는 원래의 질문에 대문자를 사용하는 예를 제시했다. 환영합니다. :-)
Sean Reifschneider

무슨 일이 일어나고 있으며 왜 솔루션이 작동하는지 설명 할 수 있다면 +1이 추가됩니다.
Jed Daniels

거기 있습니다, @Jed.
Sean Reifschneider 1

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

또는 파이썬에서 :

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'))

파이썬 버전은 16 개의 와이드 필드 만 사용하여 16 진 문자를 생성하므로 주석 처리를 위해 수정 된 접근 방식을 사용할 필요가 없습니다.


당신이 각각의 예를 제공한다면 여분의 +1 (나는 당신이 그에게 낚시하는 법을 가르치고 있다는 것을 알고 있지만, 퍼즐 조각을 만들어서 어떻게 작동하는지 / 왜 설명 할 수 있는지).
Jed Daniels

@Jed Daniels-완료 및 완료 코드가 제공되었습니다.
RobotHumans

이 코드는 몇 가지 잘못된 MAC을 생성합니다. 그것은 1000 번 반복 내가 좋아하는 몇 가지 맥을 가지고 00-60-2F-8B-5-2C, 00-60-2F-A-71-97, 00-60-2F-82-F1-4.
Bruno Finger

OP가 배쉬를 고집 한 이후로 내가 버린 것입니다. 당신은 작은 숫자를 0으로 채우는 방법을 알 수 없다는 것을 말하고 있습니까? @BrunoFinger
RobotHumans

255 대신 16을 사용하고 제로 자리 표시자를 생성하도록 쉽게 재 작업 할 수 있습니다. 더 많은 라인입니다 ...
RobotHumans

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가 정확히 무엇을 설명 할 수 있습니까? 다른 방법으로도 사용하는 것이 좋습니다!
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"

이것이 작동하는 방식의 열쇠 :

  • LC_CTYPE=C -0x7F보다 큰 문자 허용
  • IFS=- \t(탭), \n(줄 바꾸기) 및 공백의 해석을 비활성화 합니다
  • -d ''-개행 가능
  • -r허용합니다 \(거의 항상 습관으로 사용해야합니다 read)
  • 형식 지정자를 사용 -%02x\n하면 출력이 리터럴 하이픈 다음에 선행 0을 포함하는 두 자리 16 진 숫자 (해당되는 경우)가됩니다. 줄 바꿈은 여기서 불필요하며 생략 할 수 있습니다.
  • 는 0에서 255 사이 read의 단일 바이트 ( -n 1)를 가져옵니다 /dev/urandom( 00~ FF).
  • printf루프에서 마지막 인수의 작은 따옴표 는 문자를 숫자 값으로 출력합니다 ( "A"는 "65"로 출력 됨). POSIX 사양을printf 참조하십시오 .

    선행 문자가 작은 따옴표 또는 큰 따옴표 인 경우 값은 작은 따옴표 또는 큰 따옴표 뒤에 오는 문자의 기본 코드 세트의 숫자 값이어야합니다.


필요 보인다 IFS= read …00에 09 0A 20 (보통 IFS의 문자를) 접는 피하기 위해
크리스 욘센에게

@Chris : 죄송합니다. 이중 확인을하는 동안 몇 가지 작업을 수행하여 다시 넣는 것을 잊었습니다. 또한 필요합니다 -d ''. 나는 대답을 고칠 것이다. 알려 줘서 고마워.
추후 공지가있을 때까지 일시 중지되었습니다.

죄송 -r합니다.`\`을 (를) 보호합니다. 셸 프로그램에서 이진 데이터를 올바르게 처리하지 않았 으면 좋겠습니다. ☺ 문자열 중간에 정확하게 00을 나타내는 것은 불가능한 것 같습니다. 한 번에 한 문자 씩 방법은 read문자열 보간과 printf한 문자 인수를 처리하는 방법 사이의 편리한 (설계된) 협력 덕분에 00을 처리합니다 '. 한숨.
Chris Johnsen

@Chris : DWIM 프로세서가 프릿에 없었 으면 좋겠습니다. 그건 그렇고, 의 핵심 기능을 복제 한 순수한 Bash 스크립트 를 보길 원할 것입니다 hexdump -C.
추후 공지가있을 때까지 일시 중지되었습니다.

무슨 일이 일어나고 있으며 왜 솔루션이 작동하는지 설명 할 수 있다면 +1이 추가됩니다.
Jed Daniels

7

내가 얻을 수있는 가장 짧은 방법은 직접 hexdump를 사용하는 것입니다

echo 00-60-2f$(hexdump -n3 -e '/1 "-%02X"' /dev/random)
  • -n3은 16 진법으로 3 바이트를 읽도록 지시합니다.
  • 형식 문자열은 각 바이트에 대해 대시와 두 자리 16 진수 값을 인쇄합니다.
    • '/ 1'은 모든 읽기 바이트에 형식을 적용 함을 의미합니다
    • "-% 02X"는 선행 0, 2 자리, 대문자 16 진 값을 인쇄하기위한 printf 사양입니다.
  • / dev / random은 소스 랜덤 바이트입니다.

GNU / Linux에서 테스트


직장에서의 유닉스 효과 :-)
artistoex

hexdump -n3 -e'/3 "00-60-2F" 3/1 "-%02X"' /dev/random조금 짧습니다 :-)
artistoex

4

다른 한 줄 솔루션

$ 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리눅스 커널 난수 의사 파일.

  • 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


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

5
무슨 일이 일어나고 있으며 왜 솔루션이 작동하는지 설명 할 수 있다면 +1이 추가됩니다.
Jed Daniels

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
농담을 조심하십시오. 예를 들어 00-60-2F-100-A3-F6 ...와 같은 맥이 이런 식으로 "100"을 가진 이런 식으로 생성되었습니다.
petrus

@petrus 당신이 맞습니다 . 로 변경 jot -w%02X -s- -r 3 1 256하기 위해 답을 편집했습니다 jot -w%02X -s- -r 3 0 256.
nisetama

0

리눅스에서 :

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 진수로 변환 / 필터링이 필요하지 않습니다.
  • printfcutPOSIX 도구입니다;
  • UUID에 이미있는 하이픈 (구체적인 경우)을 사용합니다.

단점 :

  • UUID에서 두 개의 비임의 숫자를 염두에 두어야합니다.
  • /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.