UUDECODE - Bit-twiddling in Arexx
Author Message
UUDECODE - Bit-twiddling in Arexx

I decided I'd convert a simple C program into AREXX, so that some
network challenged types could get a simple UUDECODER going, to
unencode a better decoder.

Unfortunately I hit a snag with the bit twiddling involved!

The C bit shift operator '<<' has no Rexx equivalent.

So I'm looking for solutions to this piece of C code:

[a, b, c, and d are characters, n is an integer]

putchar((a<<2)|(b>>4));
putchar((b<<4)|(c>>2));
putchar((c<<6)|d);

Any clues?

Dac
--
David Andrew Clayton.
Canberra, Australia.

A Caring Prolix Bastard.

Tue, 17 Dec 1996 16:59:48 GMT
UUDECODE - Bit-twiddling in Arexx
I am not sure what a>>n means, but it might mean  d2c(c2d(a)//2**n).

This is not code, it is meta-REXX (sorta).  Dave

Dave Gomberg, role model for those who don't ask much in their fantasy lives.

Thu, 19 Dec 1996 01:10:34 GMT
UUDECODE - Bit-twiddling in Arexx

Quote:

} The C bit shift operator '<<' has no Rexx equivalent.
}
} So I'm looking for solutions to this piece of C code:
}
} [a, b, c, and d are characters, n is an integer]
}
}                         putchar((a<<2)|(b>>4));
}                         putchar((b<<4)|(c>>2));
}                         putchar((c<<6)|d);

I'd think that just brute-force would work.  But it isn't clear what the
sizes of things are: it looks like you're doing bit-field shuffling and
that everything is six bits.  So given that a,b,c,d are all 0<= x < 64
you could do:

call writech('f', d2c(((a / 16) * 4) + (b / 16)))
call writech('where', d2c(((b / 4) * 16) + (c / 2)))

And I can't figure out the last one, since it sure _looked_ like things
were only six bits [if not, look at the first one: if b is actually eight
bits, then you are OR'ing the high two bits of b on top of the low two bits
of a].

Anyhow, it isn't so hard to sort out the details, but I'd _hate_
to be doing that on a 100K file....  [on the other hand, a really-fancy
uu[en]decode for the Amiga is only 15K, and so that ought to be OK.

Note, too, that if you're ONLY going to be using this hack for distributing
uudecode, itself, then you don't need for _your_ format to be compatible
with uudecode's and you can get by with a much simpler plan.  For example,
you could just write the file out in *hex* [four bits per byte instead of
six bits per, hardly a crisis] and then easily use a writech(... x2c( ))
loop to put the file back.

/Bernie\
--

Fantasy Farm Fibers, Pearisburg, VA         (703) 921-2358

Thu, 19 Dec 1996 08:41:35 GMT
UUDECODE - Bit-twiddling in Arexx

Quote:
>I decided I'd convert a simple C program into AREXX, so that some
>network challenged types could get a simple UUDECODER going, to
>unencode a better decoder.

>Unfortunately I hit a snag with the bit twiddling involved!

>The C bit shift operator '<<' has no Rexx equivalent.

>So I'm looking for solutions to this piece of C code:

>[a, b, c, and d are characters, n is an integer]

>                        putchar((a<<2)|(b>>4));
>                        putchar((b<<4)|(c>>2));
>                        putchar((c<<6)|d);

>Any clues?

Dac:

Take a look at RxShip from Timothy Sipples. Someplace on ftp.cdrom.com.

---rony

Fri, 20 Dec 1996 17:40:17 GMT
UUDECODE - Bit-twiddling in Arexx

Quote:

} The C bit shift operator '<<' has no Rexx equivalent.
}
} So I'm looking for solutions to this piece of C code:
}
} [a, b, c, and d are characters, n is an integer]
}
}                         putchar((a<<2)|(b>>4));
}                         putchar((b<<4)|(c>>2));
}                         putchar((c<<6)|d);

I'd think that just brute-force would work.  But it isn't clear what the
sizes of things are: it looks like you're doing bit-field shuffling and
that everything is six bits.  So given that a,b,c,d are all 0<= x < 64
you could do:

call writech('f', d2c(((a / 16) * 4) + (b / 16)))
call writech('where', d2c(((b / 4) * 16) + (c / 2)))

And I can't figure out the last one, since it sure _looked_ like things
were only six bits [if not, look at the first one: if b is actually eight
bits, then you are OR'ing the high two bits of b on top of the low two bits
of a].

Anyhow, it isn't so hard to sort out the details, but I'd _hate_
to be doing that on a 100K file....  [on the other hand, a really-fancy
uu[en]decode for the Amiga is only 15K, and so that ought to be OK.

Note, too, that if you're ONLY going to be using this hack for distributing
uudecode, itself, then you don't need for _your_ format to be compatible
with uudecode's and you can get by with a much simpler plan.  For example,
you could just write the file out in *hex* [four bits per byte instead of
six bits per, hardly a crisis] and then easily use a writech(... x2c( ))
loop to put the file back.

/Bernie\
--

Fantasy Farm Fibers, Pearisburg, VA         (703) 921-2358

Thu, 19 Dec 1996 08:41:35 GMT
UUDECODE - Bit-twiddling in Arexx

Quote:

> I am not sure what a>>n means, but it might mean  d2c(c2d(a)//2**n).

> This is not code, it is meta-REXX (sorta).  Dave

Hmm.

I should have taken some time to explain the >> and << operators
in C.

Quote:
>> means bitshift to the right

<< means bitshift to the left

if I have the letter 5 (035x) it is represented as

0011 0101

If I were to >> 2 this, I would get

0100 1101

(or 4Dx)

if I were then to <<7 this, I would get

1010 0110

(or A6x, I think)

Whereas if I multiply this value by 2**7, I get something LARGE,
which is much bigger than a single byte.

REXX is great at strings, and fairly ordinary about bits.

Dac

Fri, 20 Dec 1996 21:35:44 GMT
UUDECODE - Bit-twiddling in Arexx
On Mon, 4 Jul 1994 13:35:44 GMT Andrew Clayton said:
Quote:

>> I am not sure what a>>n means, but it might mean  d2c(c2d(a)//2**n).

>> This is not code, it is meta-REXX (sorta).  Dave

>Hmm.

>I should have taken some time to explain the >> and << operators
>in C.

>>> means bitshift to the right
><< means bitshift to the left

>if I have the letter 5 (035x) it is represented as

>                           0011 0101

>If I were to >> 2 this, I would get

>                           0100 1101

>(or 4Dx)

>if I were then to <<7 this, I would get

>                           1010 0110

>(or A6x, I think)

>Whereas if I multiply this value by 2**7, I get something LARGE,
>which is much bigger than a single byte.

Since you are simply talking about 256 possible bit combinations,
why not create a variable with the answers, and simply translate
the string?  Then you can do strings, not simply one character at
a time!

Quote:
>REXX is great at strings, and fairly ordinary about bits.

>Dac

/ahw

Sat, 21 Dec 1996 17:39:01 GMT
UUDECODE - Bit-twiddling in Arexx
On Mon, 4 Jul 1994 13:35:44 GMT Andrew Clayton said:
Quote:

>REXX is great at strings, and fairly ordinary about bits.

while there are things I find lacking in Rexx, often when converting
programs from one language to another, and some feature is lacking,
it is often because you've over looked the paradigm shift.  You have
to change your way of thinking, and look for different idioms.
Rexx isn't C, nor is it COBOL.

Quote:

>Dac

/ahw

Sat, 21 Dec 1996 17:40:56 GMT
UUDECODE - Bit-twiddling in Arexx

Quote:
Andrew Clayton writes:

> I should have taken some time to explain the >> and <<
> operators in C.
>
> >> means bitshift to the right
> << means bitshift to the left
>
> if I have the letter 5 (035x) it is represented as
>
> 0011 0101
> If I were to >> 2 this, I would get
>
> 0100 1101

As you say,

> REXX is great at strings, and fairly ordinary about bits.

so why not treat it as a string problem. Something like this should
do it:

bitshift:

arg char,dir,amount

bnum = c2b(char)

if abbrev('LEFT', dir) then
return b2c( substr(bnum, amount + 1) || left(bnum,amount) )
else if abbrev('RIGHT', dir) then
return b2c( right(bnum, amount) || left(bnum,length(bnum) - amount) )
else
return 0

That seems to do the trick.

Arguments to the function would be something like:

NewChar = bitshift(5,r,2)

Sun, 22 Dec 1996 12:10:26 GMT
UUDECODE - Bit-twiddling in Arexx

Quote:

> arg char,dir,amount

Except, of course, that that would translate all the characters to
upper-case, something you probably don't want. It should be PARSE ARG,
along with upper() for the arguments used with abbrev().

Sun, 22 Dec 1996 12:34:55 GMT
UUDECODE - Bit-twiddling in Arexx

Quote:
> Note, too, that if you're ONLY going to be using this hack for distributing
> uudecode, itself, then you don't need for _your_ format to be compatible
> with uudecode's and you can get by with a much simpler plan.  For example,
> you could just write the file out in *hex* [four bits per byte instead of
> six bits per, hardly a crisis] and then easily use a writech(... x2c( ))
> loop to put the file back.

A perfect solution to the problem.  Thanks very much!

I love the net when it provides solutions!

Dac

Sat, 21 Dec 1996 18:31:47 GMT
UUDECODE - Bit-twiddling in Arexx

Quote:
>I should have taken some time to explain the >> and << operators
>in C.
>>> means bitshift to the right
><< means bitshift to the left
** This is ok but
>if I have the letter 5 (035x) it is represented as

>                           0011 0101

>If I were to >> 2 this, I would get

>                       0100 1101

This is not a shift - this is a rotate! An 8 bit rotate even. C does NOT have
an instruction that does this - you would need to write
((x & 3) << 6) | (x >> 2) to get the result.

In Rexx, turn the bytes into a binary string using C2X and X2B, then
use bitand to mask and substring operations and concatenation to put
the things together as you want. You can then turn the thing bak to hex using
B2X.

There are several faster ways using tables and translating directly to hex.

Mark Kaehny

Mon, 23 Dec 1996 00:53:16 GMT
UUDECODE - Bit-twiddling in Arexx

said:

Quote:
>Hmm.
>I should have taken some time to explain the >> and << operators
>in C.

[...couple simple examples deleted...]

I can't remember if C2B() and B2C() functions are part of the "new REXX"
or not, but given that they're available, bit shifts in one byte chunks
like this isn't hard:

BshftR: Procedure
Arg c,n
b = C2B(c)
Return B2C(Substr(b,9-n) || Left(b,8-n))

BshftL: Procedure
Arg c,n
b = C2B(c)
Return B2C(Substr(b,n+1) || Left(b,n))

Insuring that c is always exactly one character, and 0<=n<=7 is left as
an exercise for the reader.  (Oh, boy!  I've always wanted to say that!)
Besides, the simple examples provided weren't enough to indicate what
should be done in those cases.

Quote:
>REXX is great at strings, and fairly ordinary about bits.

I do believe we have a convert!  You are exactly right.  And the fact
that REXX has those qualities is a Good Thing, too.  It was designed
that way.

Bill

Quote:
>Dac

Mon, 23 Dec 1996 05:02:53 GMT
UUDECODE - Bit-twiddling in Arexx

Quote:

> >                        putchar((a<<2)|(b>>4));
> Take a look at RxShip from Timothy Sipples. Someplace on ftp.cdrom.com.

Thanks.

The reason for needing this [to send a copy of a proper UUDECODE program
to someone who is net.clueless] has ceased to exist.

Also, someone suggested that I just convert bytes to straight
hexadecimal [and double the size of the file] instead of using UUDECODE
[which only increases files by 1/3rd] which would be very simple, and
far quicker than the idiosyncracies of UUENCODING things.

Which will be my solution should the problem arise again.

I've also been informed that my understanding of C's >> and << bitshift
operators is quite wrong - it's a straight shift, and not a rotation
operation. :-(

Thanks to all those who responded.

Dac

Sun, 22 Dec 1996 20:15:40 GMT
UUDECODE - Bit-twiddling in Arexx

Quote:

>}                         putchar((a<<2)|(b>>4));
>}                         putchar((b<<4)|(c>>2));
>}                         putchar((c<<6)|d);
>I'd think that just brute-force would work.  But it isn't clear what the
>sizes of things are: it looks like you're doing bit-field shuffling and
>that everything is six bits.

Bernie, the inputs are 6 bits but the outputs are 8 bits.

Quote:
>   call writech('f', d2c(((a / 16) * 4) + (b / 16)))
>   call writech('where', d2c(((b / 4) * 16) + (c / 2)))

This looks nothing like the original program.  I can't figure out what
you are trying to do here...

Note, btw, that in order to shift right you want integer division using
the "%" operator.

Ian Collier

Sun, 22 Dec 1996 19:51:59 GMT

 Page 1 of 2 [ 18 post ] Go to page: [1] [2]

Relevant Pages