in reply to Translating non-printable ascii

You don't have to run the index 99 times to use s///. Whether it's fast enough is a matter of trying it and seeing, but the expression should be:
s/(\d\d)/chr(0x80+$1)/ge;
(actually, it's not clear what it should be, if your translations are right: 0xEC is 108 more than 0x80. But here's an example script:
$_="00 01 98 99"; s/(\d\d)/chr(0x80 + $1)/ge; @f= map {sprintf "%x", $_} unpack("C*", $_); print "@f\n";
Output:
80 20 81 20 e2 20 e3

Caution: Contents may have been coded under pressure.

Replies are listed 'Best First'.
Re^2: Translating non-printable ascii
by samurai (Monk) on Oct 04, 2004 at 17:10 UTC
    I was trying to save space by omitting the fact that "." is counted as a digit... so I'm missing the translation values for "0.", "1.", "2." etc etc. Sorry.

    I apologize, but I'm not sure I understand what your script is doing. I need to translate the other way. I need to turn ASCII 0x80 into "00", instead of the other way around. Or maybe I'm not understanding your answer. Here's a better example of what I'm trying to accomplish

    I need to turn (ascii characters in curly braces):

    MO{ASCII 0x81}B{ASCII 0x8D}CAJ{ASCII 0xA3}

    into:

    MO01B12CAJ32

    Does that explain it better?

    --
    perl: code of the samurai

      Ok, here's how I would do it the other way: Make a lookup table of the translations (since it's not straightforward base conversion):
      $_="MO\x81B\x8dCAJ\xa3"; my $start = 0x80; my %xlate = map { my $first = $_; map {(chr($start++), "$first$_")} (0..9, '.') } (0..9,'.') ; s/([\x80-\xec])/$xlate{$1}/g; print;
      The compound map builds the translation table.

      Caution: Contents may have been coded under pressure.