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

Either something is wrong with the MIME::Base64 module came with 5.8.2, or I missed something simple. (I suspected that my download was not clean, so I just downloaded again, and retested it, but ... Testing is done with active Perl on win2k)

With Perl 5.8.2, when I run the following code:

use IO::Socket; use MIME::Base64; use strict; use warnings; inspect(encode_base64("peip:930612")); sub inspect { (my $copy = shift) =~ s/([^[:print:]])/sprintf " (0x%02x) ", ord $ +1/ge; print $copy; }

It gives me:

cGVpcDo5MzA2MTI= (0x0a)

Looks like there is garbage ...

Replies are listed 'Best First'.
Re: MIME::Base64 is broken in 5.8.2?
by MADuran (Beadle) on Jan 19, 2004 at 20:50 UTC
    I duplcated the behavior on AS Perl 5.8.2 Win 2K. And a quick (very quick) look over of RFC 3548 seems to say it is broken. But I did this:

    use IO::Socket; use MIME::Base64; use strict; use warnings; my $encode = encode_base64("peip:930612"); print "$encode \n"; chomp $encode; inspect($encode); my $decode = decode_base64($encode); print "\n $decode \n"; sub inspect { (my $copy = shift) =~ s/([^[:print:]])/sprintf " (0x%02x) ", ord $ + 1/ge; print $copy; }

    I got this back:
    cGVpcDo5MzA2MTI= cGVpcDo5MzA2MTI= peip:930612
    and so worked around it.
    I wonder if it is in the *NIX version of 5.8.2/5.8.3??

    Update: The MIME spec allows CRLF characters in Base64:

    MADuran
    Who is in need of a spiffy sig

      Thanks MADuran and graff, for your help.

      I think what the module supposed to do is to have a \n inserted after every 76 characters, so that each line is no longer than 76.

      But for an encoded string that is less than 76 character long, no line-breaker should be inserted. But... fine, I think I just chomp it.

Re: MIME::Base64 is broken in 5.8.2?
by graff (Chancellor) on Jan 19, 2004 at 20:37 UTC
    Okay... it took me a while to figure out what you were actually complaining about. I gather you view it as a problem that the string returned by "encode_base64()" contains a line-feed character at the end.

    Is that really a problem? I'm actually not familiar with the relevant specs for base64, but this sort of behavior doesn't seem all that strange or surprising -- especially since there appears to be no trouble when "decode_base64()" is applied to the string returned by "encode_base64()"; the round-trip output matches the input:

    muse MIME::Base64; use strict; use warnings; my $teststr = "peip:930612"; my $testenc = encode_base64( $teststr ); my $testdec = decode_base64( $testenc ); die "ACK! MIME::Base64 is broke!\n" unless ( $testdec eq $teststr );
    Looks to me like you should expect a base64-encoded string to end with a line-feed character (or at least, this shouldn't be considered a bug). But I could be wrong, since I haven't read the spec for base64 encoding.

    (Do you know from personal experience that other perl versions behave differently?)

    update: Just tried this on 5.8.1 and 5.5.3, and noticed that the string returned by encode_base64() includes a final line-feed in all cases. Must be normal.

Re: MIME::Base64 is broken in 5.8.2?
by iburrell (Chaplain) on Jan 20, 2004 at 00:33 UTC
    The module docs describe encode_base64 takes an optional second parameter to control the end-of-line behavior. By default, it adds a line-feed every 76 characters and even short strings have it. If the second parameter is an empty string, then it is not broken into lines.
    encode_base64($string, '');
Re: MIME::Base64 is (working as designed) in 5.8.2
by BrowserUk (Patriarch) on Jan 19, 2004 at 23:52 UTC

    The =<CR> is used to indicate that the last line of the b64 data is not terminate with a newline.

    Both characters will be stripped when the data is decoded.

    When b64 data is embedded in an email, it is wrapped (with a newline) every 76 (b64) characters. If the input data does not end with a newline, it is necessary to indicate this so that a newline is not appended when the data is decoded. ......=<cr> is the way this is done.

    Update:Right conclusion (WAD), wrong interpretation. = characters are used by Base 64 to pad the last 1 or 2 bytes of data. Each 3 input bytes becomes 4 bytes of output. If there wasn't enough data in the last group of 3-bytes of the input, then the RFC calls for 1 or 2 '='s to be appended to the output to pad the group.

    The <CR> is appended to the end of every line of output. Normally each line is <76 b64 chars><cr>, with the last line shorter as required.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    Timing (and a little luck) are everything!

Re: MIME::Base64 is broken in 5.8.2?
by dws (Chancellor) on Jan 19, 2004 at 21:21 UTC
    I assume you're referring to the (0x0a) part as garbage. I don't get that from 5.8.0, using MIME::Base64 2.20 (on FreeBSD).

    0x0a is a newline, by the way.

      Yes, that newline is what I am referring to. Only [A-Za-z0-9+/=] are valid.

      The version come with 5.8.2 is 2.34. Base on your testing, sounds like it became broken after 5.8.0.

      Thanks!

Re: MIME::Base64 is broken in 5.8.2?
by Anonymous Monk on Jan 19, 2004 at 22:35 UTC
    MIME::Base64 is currently at 3.00, instead of worrying about an outdated version, go upgrade.