[comp.lang.perl] flipping bits in perl

caa@com50.c2s.mn.org (Charles Anderson) (05/31/91)

Yesterday a coworker asked me if I could flip all of the bits in the
font file he was using, and I decided to try using perl to do it.
(I could easily do it in C but I'm trying to learn perl and thought
I'd give it a go.)  I tried all sorts of things tr/\000-\377/\377-\000/
didn't work neither did s/./~$&/g in various type of things.  I even
tried unpacking it into an array and flipping from there but that wasn't
very succesful either.  I but a vec() into the code (something like
vec("blah", 0, 1) to see if the bit twiddling would start working after
that but it didn't.  I'm stumped...anybody know how to do it.  All I
really want is a bit negation or xor $ff.

-Thanks
	Charlie
-- 
/-Charles-Anderson-\   |       caa@c2s.mn.org || caa@midgard.mn.org 
\------------------/   | Com Squared Systems,          voice (612) 452-9522
The rose goes in front | 1285 Corporate Center Drive    fax  (612) 452-3607
big guy -Crash Davis   | Suite 170 | Eagan,  MN 55121  (I speak for myself)

merlyn@iWarp.intel.com (Randal L. Schwartz) (05/31/91)

In article <1991May30.231900.12417@com50.c2s.mn.org>, caa@com50 (Charles Anderson) writes:
| 
| Yesterday a coworker asked me if I could flip all of the bits in the
| font file he was using, and I decided to try using perl to do it.
| (I could easily do it in C but I'm trying to learn perl and thought
| I'd give it a go.)  I tried all sorts of things tr/\000-\377/\377-\000/
| didn't work neither did s/./~$&/g in various type of things.  I even
| tried unpacking it into an array and flipping from there but that wasn't
| very succesful either.  I but a vec() into the code (something like
| vec("blah", 0, 1) to see if the bit twiddling would start working after
| that but it didn't.  I'm stumped...anybody know how to do it.  All I
| really want is a bit negation or xor $ff.

Here's a really awfully fast program hand-tuned by Larry and me while
we were one-upping each other while writing the book.  It does exactly
what you asked for.  *How* it does it should be a useful puzzle to
figure out...

#!/usr/bin/perl
$bufsize = 16384;
vec($ones,0,8) = 255;
$ones x= $bufsize;
while(read(STDIN,$_,$bufsize)) {
	print STDOUT length != $bufsize ?
		substr($_ ^ $ones, 0, length) : $_ ^ $ones;
}

or, you can try it like this:

print pack("C*",grep(($_^=255)||1,unpack("C*",pack("H*","b58a8c8bdf9e91908b979a8ddfaf9a8d93df979e9c949a8dd3"))))
-- 
/=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\
| on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III      |
| merlyn@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn |
\=Cute Quote: "Intel: putting the 'backward' in 'backward compatible'..."====/

lwall@jpl-devvax.jpl.nasa.gov (Larry Wall) (06/01/91)

In article <1991May31.162709.7069@iWarp.intel.com> merlyn@iWarp.intel.com (Randal L. Schwartz) writes:
: In article <1991May30.231900.12417@com50.c2s.mn.org>, caa@com50 (Charles Anderson) writes:
: | 
: | Yesterday a coworker asked me if I could flip all of the bits in the
: | font file he was using, and I decided to try using perl to do it.
: | (I could easily do it in C but I'm trying to learn perl and thought
: | I'd give it a go.)  I tried all sorts of things tr/\000-\377/\377-\000/

You can't give negative ranges like \377-\000.  You could construct one and
eval it, however.

: | didn't work neither did s/./~$&/g in various type of things.  I even

You'd have to say pack(C,~unpack(C,$&)), or some such.

: | tried unpacking it into an array and flipping from there but that wasn't
: | very succesful either.  I but a vec() into the code (something like
: | vec("blah", 0, 1) to see if the bit twiddling would start working after
: | that but it didn't.  I'm stumped...anybody know how to do it.  All I
: | really want is a bit negation or xor $ff.
: 
: Here's a really awfully fast program hand-tuned by Larry and me while
: we were one-upping each other while writing the book.  It does exactly
: what you asked for.  *How* it does it should be a useful puzzle to
: figure out...
: 
: #!/usr/bin/perl
: $bufsize = 16384;
: vec($ones,0,8) = 255;
: $ones x= $bufsize;
: while(read(STDIN,$_,$bufsize)) {
: 	print STDOUT length != $bufsize ?
: 		substr($_ ^ $ones, 0, length) : $_ ^ $ones;
: }

Note that there's a bug in vector ^ (in 4.003) that may prevent this
from working.  It might work to use the assignment operator, $_ ^= $ones,
however.

Larry