Перевод шеснадцатиричного представления IP в стандартную форму в конс


ramok аватар

ramok - Posted on 11 Январь 2006

перевод hex IP -> dec IP

1) bash only by ams

$ i=ffffffc0; echo $((0x${i:0:2})).$((0x${i:2:2})).$((0x${i:4:2})).$((0x${i:6:2}))

2) так короче но $[] dericated

$ i=ffffffc0; echo $[0x${i:0:2}].$[0x${i:2:2}].$[0x${i:4:2}].$[0x${i:6:2}]

3) тоже вроде только для bash как имеющий опцию -n в read

$ echo ffffffc0 | while read -n 2 D; do [ -z $D ] || printf "%d." 0x$D; done; echo

4) sh+sed

$ printf "%d.%d.%d.%d\n" `echo ffffffc0 | sed 's/\(..\)\(..\)\(..\)\(..\)/0x\1 0x\2 0x\3 0x\4/'`

5) тоже но немного разбираясь в sed Ж:-)

$ printf "%d.%d.%d.%d\n" `echo ffffffc0 | sed 's/\(..\)/0x\1 /g'`

6) printf only by ams. но это только смотреть, пайпы не пройдут Ж:-)

$ i=ffffffc0;  printf "         0x%s\r        %.6s 0x\r     %.4s 0x\r0x%.2s 0x\n" $i $i $i $i

7) на bash by SmileX@RusNet

$ i=ffffffc0; (let n=0x$i; for (( i=4;i>0;i-- )); do o=$((n%256)).$o; let n/=256; done; echo -e $o"\b ")

8) perl и perl+bash by ams

$ echo ffffffc0 | perl -pe 's/(..)/hex($1)."."/eg;s/.$//'
$ perl -pe's/(..)/hex($1)."."/eg;s/.$//'<<<ffffffc0

9) dc by ams (круть! Ж:-)

$ i=FFFFFFFC;dc -e16i$i[100~r[.]rla]dSaxxxSannnnnnp

10) sed

$ echo ffffffc0 | sed -e's/../printf "%d." 0x&;/ge' -e's/.$//'

11) ваш вариант? Ж:-)

0
Ваша оценка: Ничего

11) ipcalc ffffffc0

~ $ i=ffffffc0; (let n=0x$i; for (( i=4;i>0;i-- )); do o=$((n%256)).$o; let n/=256; done; echo -e $o"\b ")
255.255.255.192

PS шото с n>>=8 не захотело работать...

SmileX@RusNet

Собственно говоря, нечто подобное и было моим первым решением этой задачки (которая родилась где-то в ноябре 2005 на irc-канале #linux):

i=ffffffc0; echo $((0x$i>>24)).$((0x$i>>16&255)).$((0x$i>>8&255)).$((0x$i&255))

У меня это заработало и я кинул скриптик на канал. Однако вопрошающий ответил, что у него это не работает. Оказалось, что у него Солярис. Я подключился к Солярису и в ответ получил -1.255.255.192. Быстрое исследование показало, что на Солярисе числа в bash'e имеют длину 32 бита, а на Линуксе - 64 бита. Поэтому:

SunOS$ echo $((0xffffffff))
-1
Linux$ echo $((0xffffffff))
4294967295
Linux$ echo $((0xffffffffffffffff))
-1

В результате на Солярисе не работают правильно ни сдвиг >>, ни деление % / (знак минус сохраняется).

Предложенный выше SmileX цикл на доступной мне машине проверить не удалось, ибо там есть только GNU bash, version 2.02.1(1)-release (sparc-sun-solaris2.5.1), который ругается на syntax error near unexpected token `(('. Если развернуть цикл вручную, то результат на Линуксе правильный, а на Солярисе: 0.0.0.-64.

Вот поэтому-то как первый вариант и родился скрипт, который вместо арифметических действий оперировал со строками.

echo ffffffc0 | perl -pe 's/(..)/hex($1)."."/eg;s/.$//'

используя перенаправление в bash, можно сэкономить еще 6 символов :)

perl -pe's/(..)/hex($1)."."/eg;s/.$//'<<<ffffffc0

---
ams

ну перл тут может кому угодно фору дать Ж:-)
gnu sed тоже умеет запускать из себя команды
echo ffffffc0 | sed -e's/../printf "%d." 0x&;/ge' -e's/.$//'

--
Signature invent in progress 19% #.........

i=FFFFFFFC;dc -e16i$i[100~r[.]rla]dSaxxxSannnnnnp

---
ams

ух ты, кайф Ж8-) могёёш...

/me пошел читать man dc

--
Signature invent in progress 19% #.........

Отправить комментарий

Google Friend Connect (leave a quick comment)
loading...
Содержание этого поля является приватным и не предназначено к показу.