[alt.sources] byte-order calculator

lee@sq.sq.com (Liam R. E. Quin) (12/06/89)

Did you ever look at an octal (or hex, or...) dump of something and say to
yourself, `well, those three bytes might represent the size of the...'?

I wrote the following little calculator... you can say

	371 10 1 0
and it comes back with
		0... 1... 264... 67833... 
	dec 67833 oct 0204371 hex 0x108f9

so you can see that if these four octal bytes were stored in memory, they'd
represent the decimal number 67833 (assuming intel byte ordering).  You can
type any reasonable number of clumps of digits to make an n-byte word.
You can change the byte ordering and the bases used:
	sane, mc68k, mc68000 -- least significant "clump" is on the left
	intel, vax -- least significant "clump" is on the right
so it does a b c d and d c b a, but not b a d c.  You could easily change it.
Note that byte ordering only affects the order in which clumps of digits are
processed, not the digits within the clumps, so
	intel		and		sane
	10 23 45 			45 23 10
are equivalent.

The bases can be changed with ibase (for the base you're using to type
the byte values) and obase (to tell it what constitutes a byte -- default is
256, of course, but if you use 1 you get a primitive adding machine :-).
You can say "obase hex" or "ibase = 10" -- either syntax is known.  Of course,
saying "ibase = 10" is always a no-op, so the following are also known:
    hex (or hexadecimal) = 16, oct (octal) = 8, byte = 256, dec(imal) = 10
Oh, and "info" gives current status information.

[ anyway, time for the awk-lovers to hit back against the evil perl :-) :-)]

Lee

: To unbundle, sh this file
a - bcalc
echo x - bcalc 1>&2
sed 's/^X//' >bcalc <<'@@@End of bcalc'
X#! /usr/local/bin/nawk -f
X
X# Liam Quin's very simple byte calculator.
X# On system V, use nawk -f this-file-name, perhaps in a little shell-script.
X# Needs the new awk (nawk on SysV, or MKS awk, or from the AT&T toolchest)
X
XBEGIN {
X    convtype = "octal"; obase = 256; ibase = 8; clumpbase = 256
X    intel = 1 # Well, you can change it if you want
X    for (i = 0; i < 10; i++) {
X	values[i ""] = i
X    }
X    # set up octal/hex/arbitrary base digits
X    values["a"] = 10 values["A"] = 10 values["b"] = 11 values["B"] = 11
X    values["c"] = 12 values["C"] = 12 values["d"] = 13 values["D"] = 13
X    values["e"] = 14 values["E"] = 14 values["f"] = 15 values["F"] = 15
X
X    radix["octal"] = 8 radix["oct"] = 8
X    radix["decimal"] = 10 radix["dec"] = 10
X    radix["hexadecimal"] = 16 radix["hex"] = 16
X    radix["sex"] = 60 radix["byte"] = 256 # output only...
X    radix["liam"] = 42
X}
X
X/^[ 	]*$/ { next }
X
X# clumpbase lets you specify the base with which clumps are combined
X# Allow built-in keywords like "obase hex" for sanity...
X($1 == "clumpbase" || $1 == "obase" || $1 == "cbase") {
X    if (NF == 3 && ($2 == "=" || $2 == "==")) clumpbase = $3
X    else clumpbase = $2
X    if (clumpbase in radix) {
X	clumpbase = radix[clumpbase]
X    } else if (clumpbase ~ /^[0-9a-fA-F]+$/) {
X	tmp = conv(clumpbase)
X	clumpbase = tmp # might not get here if conv() does a "next"
X    }
X    printf "obase set to %d (0%o, 0x%x)\n", clumpbase, clumpbase, clumpbase
X    next
X}
X
X# conv lets you specify how the lumps within the clumps are interpreted.
X# max is currently 16
X($1 == "ibase") {
X    if (NF == 3 && ($2 == "=" || $2 == "==")) convtype = $3
X    else convtype = $2
X    if (convtype in radix) {
X	ibase = radix[convtype]
X    } else if (convtype ~ /^[0-9a-fA-F]+$/) {
X	tmp = conv(convtype)
X	if (tmp > 16) {
X	    printf "Largest supported base is 16, sorry (runs out of digits)\n"
X	    printf "%d is too big.\n", tmp
X	    next
X	}
X	ibase = tmp # might not get here if conv() does a "next"
X    } else {
X	printf "Invalid conv type \"%s\"\n", convtype
X	next
X    }
X    printf "ibase set to %s (base %d [decimal])\n", convtype, ibase
X    next
X}
X
X(NF == 1) {
X    if ($1 ~ /^[qQ]([uU][iI][tT])?/) { exit 0 }
X    else if ($1 == "help") {
X	print "You're on your own, boy!"
X	printf "\t\t\t\t\t\t(info is better)\n"
X	next
X    } else if ($1 == "info") {
Xprint "bcalc -- very simple byte calculator"
Xprint "  clumps of digits are each read in base \"ibase\", and are combined"
X	if (intel) printf "  (right to left) "
X	else printf "  (left to right) "
Xprint "  as if they were each digits in base \"obase\"."
Xprintf "  Change the bases (currently obase=%d, ibase=%d) with the\n",
X					obase,     ibase
Xprint "  obase and ibase commands."
Xprint "  Use \"intel\" or \"sane\" to control byte ordering.\n"
X	next
X    } else if ($1 == "intel" || $1 ~ /^[vV][aA][xX]$/) {
X	intel = 1
X	print "Using looney clump ordering, lsb on left"
X	next
X    } else if ($1 == "sane" || $1 ~ /^[mM][cC]68(0|[kK])+/) {
X	intel = 0
X	print "Using sane clump ordering, lsb on right"
X	next
X    }
X}
X
X(NF > 0) {
X    val = 0
X    printf "\t"
X    if (intel) {
X	for (i = NF; i >= 1; i--) {
X	    val = val * clumpbase
X	    val = val + conv($(i))
X	    printf "%d... ", val
X	}
X    } else {
X	for (i = 1; i <= NF; i++) {
X	    val = val * clumpbase
X	    val = val + conv($(i))
X	    printf "%d... ", val
X	}
X    }
X    printf "\n"
X    printf "dec %d oct 0%o hex 0x%x\n", val, val, val
X    next
X}
X
X{
X    print "Error: "
X    print
X    next
X}
X
Xfunction conv(n,  r, s, d, l, dig)
X{
X    if (ibase == 10) { # special case
X	if (n ~ /^[0-9]+$/) return n
X	else printf "Decimal %s contains strange numbers...\n", n
X	next
X    } else {
X	if (convtype == "octal" && !(n ~ /^[0-7]+$/)) {
X	    printf "Octal %s contains strange numbers...\n", n
X	    next
X	}
X	r = 0
X	s = "0" n
X	l = length(s)
X	for (d = 1; d <= l; d++) {
X	    dig = substr(s, d, 1)
X	    if (dig == "") dig = "0" # mks awk bug (mks sucks)
X	    # printf "\ts is \"%s\", l is %d, d is %d, dig is \"%s\"\n",
X		#	       s,	l,	  d,	      dig
X	    if (dig in values) {
X		if (values[dig] >= ibase) {
X		    printf "base %d [dec] number has illegal digit %s\n",
X							ibase, dig
X		    next
X		}
X		r = r * ibase + values[dig]
X	    } else {
X		printf "\"%s\" contains strange digit \"%s\" (not hex)\n",
X					n, dig
X		next
X	    }
X	}
X	return r
X    }
X}
@@@End of bcalc
-- 
Liam R. Quin, Unixsys (UK) Ltd [note: not an employee of "sq" - a visitor!]
lee@sq.com (Whilst visiting Canada from England, until Christmas)
 ...striving to promote the interproduction of epimorphistic conformability