vegasjoe has asked for the wisdom of the Perl Monks concerning the following question:

I am looking for a explanation of the following transliteration:
$str =~ tr|A-Za-z0-9+/| -_|; # convert to uuencoded format
I know so far that the "tr///" operator performs a substitution on the individual characters in a string. I know how to build at uuencoded string by hand. By taking the ASCII decimal value of the character, then converting the ASCII to binary. Next shifting the left 6 bits and converting back to decimal. Next, add 32 to the new value to get a ASCII code back (A_Za-z0-9+/). So my question is how does the following do that in one step?
$str =~ tr|A-Za-z0-9+/| -_|;
This code snippet comes from MIME::Base64::Perl decode_base64() function.

Replies are listed 'Best First'.
Re: Converting To Uuencoded Format
by ikegami (Patriarch) on Dec 11, 2008 at 18:02 UTC

    how does the following do that in one step?

    It's a lookup table.

    ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_

    The tr/// pattern condenses the table into ranges.
    The description you gave condenses the table into a math formula.

Re: Converting To Uuencoded Format
by gone2015 (Deacon) on Dec 11, 2008 at 18:20 UTC

    What this is doing is converting Base64 to uuencoded format. They both encode 6 bits per character, but use different characters -- Base64 uses 'A' to encode 0, where uuencode uses ' ' or "`"; Base64 uses 'B' for 1, uuencode uses '!'; and so on, as per the  tr|A-Za-z0-9+/| -_| you quote.

    You'll see that the uuencoded characters are decoded elsewhere.

Re: Converting To Uuencoded Format
by ig (Vicar) on Dec 11, 2008 at 20:21 UTC
    how does the following do that in one step?

    It doesn't. The comment is misleading.

    It translates the characters used to represent each six bit chunk of the data. Both uuencode and Base64 encodings break the original data into chunks of six bits and use one character to represent each chunk, but they use different characters to represent each chunk.

    There are other differences in the format of Base64 and uuencoded messages. They both break the encoded data up into lines with a maximum length. Uuencode prefixes each line with the number of bytes of original data encoded in the line. And both have header and footer lines. Much of the rest of the subroutine deals with breaking up the encoded data and adding the byte count prefixes.

    In MIME::Base64::Perl, pack and unpack are used to translate between uuencoded data (less the header and footer lines) and the original data. It is pack (with the 'u' encoding specified) that does what you describe. And in decode_base64 unpack is used to convert from the uuencoded form (less the header and footer lines) back to the original data.