On 6/20/07, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote:
current problem is, given an ip address, say 135.104.9.7 and an ip mask, say 255.255.255.0,how do i get the result of addr & mask using only sed and echo?
sitting idly at usenix, not listening to the boring talks. it can be done, but it's not pretty. hope you don't mind the 36 seconds it takes to compute: parr% date; andip 123.124.125.126 255.255.0.127; date Fri Jun 22 13:43:48 EDT 2007 123.124.0.126 Fri Jun 22 13:44:24 EDT 2007 parr% now i think i'll go to the beach.
#################### # helper functions # #################### fn mshift { shift echo $* } fn reverse { switch($#*) { case 1 echo $1 case * echo `{reverse `{mshift $*}} $1 } } fn split { n = $1 shift if(~ $n '') { echo $* | sed 's/(.)/\1 /g' } if not{ echo $* | sed 's/'^$n^'/ /g' } } fn join { echo $* | sed 's/ //g' } fn length { echo $#* } fn pad { } #################### fn and1 { switch($#*) { case 2 if(~ $1 1 && ~ $2 1) { echo 1 } if not{ echo 0 } case 1 echo NaN } } fn and { { switch($#*) { case 2 n = (`{split '' $2}) * = (`{split '' $1}) while(! ~ $#* 0) { echo -n `{and1 $1 $n(1)}^' ' shift n = `{mshift $n} } } }| sed 's/ $//;s/ //g' } fn or1 { switch($#*) { case 2 if(~ $1 0 && ~ $2 0) { echo 0 } if not{ echo 1 } } } fn or { { switch($#*) { case 2 n = (`{split '' $2}) * = (`{split '' $1}) while(! ~ $#* 0) { echo -n `{or1 $1 $n(1)}^' ' shift n = `{mshift $n} } } }| sed 's/ $//;s/ //g' } fn cmp1 { n = '' switch($1) { case 0 switch($2) { case 0 n = 0 case 1 n = 1 } case 1 switch($2) { case 0 n = -1 case 1 n = 0 } case * n = NaN } echo $n } fn cmpb { res = 0 switch($#*) { case 2 one = `{split '' $1} two = `{split '' $2} if(~ $#one $#two) { while(! ~ $#one 0 && ~ $res 0) { res = `{cmp1 $one(1) $two(1)} one = `{mshift $one} two = `{mshift $two} } echo $res } if not { while(! ~ $#one 0 && ! ~ $#two 0) { one = `{mshift $one} two = `{mshift $two} } if(! ~ $#one 0) { echo -1 } if not { echo 1 } } } } fn cmp { switch($#*) { case 2 cmpb `{tobin $1} `{tobin $2} } } fn modtwo1 { switch ($1) { case 2 4 6 8 0 n = 0 case 1 3 5 7 9 n = 1 case * n = NaN } echo $n } fn modtwo-long { n = $* modtwo1 $n($#n) } fn modtwo { modtwo-long `{split '' $1} } fn divtwo1 { switch ($1) { case 0 n = 0 case 1 n = (0 1) case 2 n = 1 case 3 n = (1 1) case 4 n = 2 case 5 n = (2 1) case 6 n = 3 case 7 n = (3 1) case 8 n = 4 case 9 n = (4 1) case 10 n = 5 case 11 n = (5 1) case 12 n = 6 case 13 n = (6 1) case 14 n = 7 case 15 n = (7 1) case 16 n = 8 case 17 n = (8 1) case 18 n = 9 case 19 n = (9 1) } echo $n } fn divtwo-long { switch($#*) { case 1 n = (`{divtwo1 $1}) echo $n(1) case * n = (`{divtwo1 $1}) switch($#n) { case 1 echo $n(1) `{divtwo-long `{mshift $*}} case 2 z = (`{mshift $*}) echo $n(1) `{divtwo-long $n(2)^$z(1) `{mshift $z}} } } } fn divtwo { divtwo-long `{split '' $1} |sed 's/ //g;s/^0+(.+)/\1/' } fn addone1 { switch ($1) { case 0 n = 1 case 1 n = 2 case 2 n = 3 case 3 n = 4 case 4 n = 5 case 5 n = 6 case 6 n = 7 case 7 n = 8 case 8 n = 9 case 9 n = (0 1) case * n = NaN } echo $n } fn addone-long { # big-endian z = `{split '' $1} switch($#*) { case 1 n = (`{addone1 $z}) switch($#n) { case 1 echo $n `{mshift $*} case 2 echo $n(1) $n(2) } case * n = `{addone1 $z} switch($#n) { case 1 echo -n $n(1) `{mshift $*} case 2 nz = `{mshift $*} echo -n $n(1) `{addone-long $nz(1)^$n(2) `{mshift $nz}} } } } fn addone { join `{reverse `{addone-long `{reverse `{split '' $1}}}} } fn multwo1 { switch ($1) { case 0 n = 0 case 1 n = 2 case 2 n = 4 case 3 n = 6 case 4 n = 8 case 5 n = (0 1) case 6 n = (2 1) case 7 n = (4 1) case 8 n = (6 1) case 9 n = (8 1) } if(~ $#* 2) { switch($#n) { case 2 n = (`{addone1 $n(1)} $n(2)) case 1 n = `{addone $n} } } echo $n } fn multwo-long { # big-endian z = `{split '' $1} switch($#*) { case 1 n = `{multwo1 $z} switch($#n) { case 1 echo $n case 2 echo $n(1) $n(2) } case * n = `{multwo1 $z} nn = `{mshift $*} switch($#n) { case 1 echo $n `{multwo-long $nn} case 2 echo $n(1) `{multwo-long $nn(1)^$n(2) `{mshift $nn}} } } } fn multwo { join `{reverse `{multwo-long `{reverse `{split '' $1}}}} } fn tobin-long { n = `{divtwo $1} if(! ~ $n 0) { echo -n `{tobin-long `{divtwo $1}} `{modtwo $1} } if not { modtwo $1 } } fn tobin { join `{tobin-long $1} } fn padb { # pad the first binary number with zeros until # it becomes as long as the second # # user must ensure that the first argument is # numerically less than the second one = `{split '' $1} two = `{split '' $2} while(! ~ $#one $#two) { one = ('0' $one) } echo `{join $one} } fn todec-long { # rear-endian switch ($#*) { case 1 switch($1) { case 1 echo -n 1 case * echo -n NaN # can not end with a zero } case * switch ($1) { case 0 multwo `{todec-long `{mshift $*} } case 1 addone `{multwo `{todec-long `{mshift $*} } } } } } fn todec { switch($1) { case 0 echo 0 case * join `{reverse `{todec-long `{reverse `{split '' $1}}}} } } #################################################### fn andip1 { switch($#*) { case 2 ns = `{tobin $1} nn = `{tobin $2} switch(`{cmpb $nn $ns}) { case -1 ns = `{padb $ns $nn} case 1 nn = `{padb $nn $ns} } r = `{and $ns $nn} todec `{echo $r |sed 's/^0+(.+)$/\1/'} case * echo NaN } } fn andip { { n = (`{split '\.' $2 }) * = (`{split '\.' $1 }) if(~ $#n $#*) { while(! ~ $#* 0) { echo -n `{andip1 $n(1) $1}^' ' shift n = `{mshift $n} } } if not { echo 'number of quads must match' } }| sed 's/ $//;s/ /./g' }