#!/bin/sh ################################################################# # # @(#) d2x.sh (c) 2021 by H. Zuleger HZNET # # convert integer values between different number systems # # - run the script with option --install-script within the # installation directory to create all the needed links # # d2? convert decimal to hexdecimal,octal,binary # x2? convert hexadecimal to decimal,octal,binary # o2? convert octal to hexadecimal,decimal,binary # b2? convert binary to hexadecimal,decimal,octal # # Apr 2022 # - leading zeroes up to nibble, byte or word # boundary added # # Sep 2022 # - use of dc(1) to add the leading zeroes # - adding of double word boundary # - boundary changed to option -n -b -w and -d # - option -6 for IPv6 address parsing (uses x2?) # - option -s added for spacing of hex and binary output # # Oct 2022 # - fixed bug in option -6 # # Feb 2023 # - option -4 added to parse IPv4 addresses (uses d2?) # - test if argument is an ip address # ################################################################# PATH=/bin:/usr/bin # default is decimal i=10 o=10 boundary=0 spacing=0 prog=`basename $0` install() { ns="b o d x" for from in $ns do for to in $ns do test $from = $to && continue new="${from}2${to}" test $prog != $new && ln $prog $new done done exit } usage() { test -n "$1" && echo "$1" 1>&2 echo "usage: $prog [{-nibble|-byte|-word|-doubleword} [-s]] value [...]" 1>&2 echo "usage: $prog [{-4|-6}] [-s] {ipv4address|ipv6address}" 1>&2 exit 1 } case $prog in b2?) i=2 ;; o2?) i=8 ;; d2?) i=10 ;; x2?) i=16 ;; *) usage ;; esac case $prog in ?2b) o=2 ;; ?2o) o=8 ;; ?2d) o=10 ;; ?2x) o=16 ;; *) usage ;; esac ip=0 while test $# -gt 0 do case $1 in --install-script|install-script) install ;; -n*) boundary=4 ;; -b*) boundary=8 ;; -w*) boundary=16 ;; -d*) boundary=32 ;; -4) ip=4 i=10 boundary=8 ;; -6) ip=6 i=16 boundary=16 ;; -s*) spacing=8 ;; -*) usage "Illegal option $1" ;; *) break ;; esac shift done test $# -lt 1 && usage "Missing base $i integer argument" # parse argument if it looks like an ip address case "$1" in *.*) i=10; ip=4; boundary=8 ;; *:*) i=16; ip=6; boundary=16 ;; esac # boundary makes sense on binary or hex output if test $boundary -gt 0 then case $o in 2) ;; 16) boundary=`expr $boundary / 4` spacing=`expr $spacing / 2` ;; *) boundary=0 ;; esac fi if test $ip -eq 6 # split ipv6 address on colon blocks then set `echo "$@" | tr -c "[0-9A-Fa-f]" " "` elif test $ip -eq 4 # split ipv4 address on dots then set `echo "$@" | tr -c "[0-9]" " "` fi { echo "$o o" echo "$i i" for v in "$@" do # echo "$v" | tr "[abcdef]" "[ABCDEF]" | tr -cd "[A-F0-9]" echo "$v" | tr "[abcdef]" "[ABCDEF]" | tr -c "[A-F0-9]" " " echo "p c" done } | dc | if test $boundary -gt 0 then while read line do dc -e "$o o [d0&2 # # if test $fill -ne $boundary # then # zeroes=`yes 0 | sed ${fill}q | tr -d "\012"` # fi #fi #echo $zeroes$line done | { tr -d "\012" echo } | if test $spacing -gt 0 then pat=`echo "........" | cut -c1-$spacing` sed "s/$pat/& /g" else cat fi else cat fi