Заменить шестнадцатеричный символ другим случайным (возможно?) - PullRequest
0 голосов
/ 02 марта 2019
У

есть MAC-адрес, и мне нужно заменить только один шестнадцатеричный символ (один в очень конкретной позиции) на другой случайный (он должен отличаться от оригинала).Я сделал это таким образом, используя xxd, и он работает:

#!/bin/bash
mac="00:00:00:00:00:00" #This is a PoC mac address obviously :)
different_mac_digit=$(xxd -p -u -l 100 < /dev/urandom  | sed "s/${mac:10:1}//g" | head -c 1)
changed_mac=${mac::10}${different_mac_digit}${mac:11:6}
echo "${changed_mac}" #This echo stuff like 00:00:00:0F:00:00

Проблема для моего сценария заключается в том, что использование xxd означает другую зависимость ... Я хочу ее избежать (не во всех Linux естьвключен по умолчанию).У меня есть другой обходной путь для этого с помощью команды hexdump, но, используя ее, я на той же стадии ... Но мой сценарий уже имеет обязательную зависимость awk, так что ... Можно ли это сделать с помощью awk?Мне нужен мастер awk здесь :) Спасибо.

Ответы [ 5 ]

0 голосов
/ 02 марта 2019
$ mac="00:00:00:00:00:00"
$ awk -v m="$mac" -v p=11 'BEGIN{srand(); printf "%s%X%s\n", substr(m,1,p-1), int(rand()*15-1), substr(m,p+1)}'
00:00:00:01:00:00
$ awk -v m="$mac" -v p=11 'BEGIN{srand(); printf "%s%X%s\n", substr(m,1,p-1), int(rand()*15-1), substr(m,p+1)}'
00:00:00:0D:00:00

И чтобы убедиться, что вы получили цифру, отличную от той, с которой вы начали:

$ awk -v mac="$mac" -v pos=11 'BEGIN {
    srand()
    new = old = toupper(substr(mac,pos,1))
    while (new==old) {
        new = sprintf("%X", int(rand()*15-1))
    }
    print substr(mac,1,pos-1) new substr(mac,pos+1)
}'
00:00:00:0D:00:00
0 голосов
/ 02 марта 2019

Другой awk:

$ awk -v n=11 -v s=$RANDOM '                # set n to char # you want to replace
BEGIN { FS=OFS="" }{                        # each char is a field
    srand(s)                                
    while((r=sprintf("%x",rand()*16))==$n);  
    $n=r
}1' <<< $mac

Выход:

00:00:00:07:00:00

или oneliner:

$ awk -v n=11 -v s=$RANDOM 'BEGIN{FS=OFS=""}{srand(s);while((r=sprintf("%x",rand()*16))==$n);$n=r}1' <<< $mac
0 голосов
/ 02 марта 2019

Вам не нужно xxd или hexdump.urandom также будет генерировать числа, которые соответствуют кодировкам цифр и букв, используемых для представления шестнадцатеричных чисел, поэтому вы можете просто использовать

old="${mac:10:1}"
different_mac_digit=$(tr -dc 0-9A-F < /dev/urandom | tr -d "$old" | head -c1)

Конечно, вы можете заменить весь ваш скрипт на awkсценарий тоже.Следующий скрипт GNU awk заменит 11-й символ каждой строки случайным шестнадцатеричным символом, отличным от старого.С <<< macaddress мы можем подать macaddress на его стандартный ввод, не используя echo или что-то в этом роде.

awk 'BEGIN { srand(); pos=11 } {
  old=strtonum("0x" substr($0,pos,1))
  new=(old + 1 + int(rand()*15)) % 16
  print substr($0,1,pos-1) sprintf("%X",new) substr($0,pos+1)
}' <<< 00:00:00:00:00:00

Хитрость заключается в добавлении случайного числа от 1 до 15 (оба включительно).) к цифре, подлежащей изменению.Если мы получим число больше 15, мы обернемся, используя оператор по модулю % (16 становится 0, 17 становится 1 и т. Д.).Таким образом, результирующая цифра гарантированно будет отличаться от старой.

Тем не менее, тот же подход будет короче, если будет полностью написан на bash.

mac="00:00:00:00:00:00"
old="${mac:10:1}"
(( new=(16#"$old" + 1 + RANDOM % 15) % 16 ))
printf %s%X%s\\n "${mac::10}" "$new" "${mac:11}"

«Однострочная» версия:

mac=00:00:00:00:00:00
printf %s%X%s\\n "${mac::10}" "$(((16#${mac:10:1}+1+RANDOM%15)%16))" "${mac:11}"
0 голосов
/ 02 марта 2019

Примерно так может работать с начальным значением из $RANDOM:

mac="00:00:00:00:00:00"
awk -v seed=$RANDOM 'BEGIN{ FS=OFS=":"; srand(seed) } {
   s="0"
   while ((s = sprintf("%x", rand() * 16)) == substr($4, 2, 1))
   $4 = substr($4, 1, 1) s
} 1' <<< "$mac"

00:00:00:03:00:00

Внутри цикла мы продолжаем, пока шестнадцатеричная цифра не станет равной substr($4, 2, 1), что2-й символ 4-го столбца.

0 голосов
/ 02 марта 2019

bash имеет встроенную функцию printf и случайную функцию (если вы ей доверяете):

different_mac_digit() {
    new=$1
    while [[ $new = $1 ]]; do
        new=$( printf "%X" $(( RANDOM%16 )) )
    done
    echo $new
}

Вызывает символ, подлежащий замене в качестве аргумента.

...