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

Reply via email to