Base 64 encode/decode

The following applications invoke the tcllib base64 encoding/decoding package.

They are intended to be a pair of applications allowing the user to encode an arbitrary file or data presented on standard input, or decode an encoded file or data .

[NOTE: There is something wrong with the code at the bottom - it doesn't work exactly. If I run

        encoder < file1 | decoder > file2 ; cmp file1 file2

sometimes I get a match and sometimes no match. Anyone see what is going wrong?


RS: Could it be that base64 puts 6 bits into one byte, so for some files the length is not divisible both by 6 and 8? (I mean, some bits are finally left over, and are maybe padded into a blank or so?)

AK: The encode command auto-pads its output with '=' for input lengths not 0 modulo 3, and the decode command recognizes such padding and strips it properly. IMHO an example of input exhibiting the problem should be provided, without debugging is like walking through fog.


APN Note that 8.6 has a binary encode/decode base64 built-in commands [L1 ].


 #! /usr/tcl84/bin/tclsh
 package require base64
 # Purpose: read stdin or a file on the argument line and output to stdout
 #      a base64 encoding of the file.
 # Version 1.0 by [Larry W. Virden]
 # Version 1.1 by [Larry W. Virden] and [Andreas Kupries]
 
 if { $argc > 0 } {
        set fin [open [lindex $argv 0] "r"]
 } else {
        set fin stdin
 }
 fconfigure $fin -encoding binary
 while { ! [eof $fin] } {
        set input [read $fin 72]
        puts [::base64::encode $input]
 }
 close $fin

LGT: I added "-maxlen 96" to produce a cleaner output (96 = 72 * 4 / 3)

        puts [::base64::encode -maxlen 96 $input]

 #! /usr/tcl84/bin/tclsh

 package require base64
 # Purpose: read stdin or a file on the argument line and output to stdout
 #      a base64 decoding of the file.
 # Version 1.0 by [Larry W. Virden]
 # Version 1.1 by [Larry W. Virden] and [Andreas Kupries]
 
 if { $argc > 0 } {
        set fin [open [lindex $argv 0] "r"]
 } else {
        set fin stdin
 }
 fconfigure stdout -encoding binary
 while { ! [eof $fin] } {
        set input [gets $fin]
        puts -nonewline stdout [::base64::decode $input]
 }
 close $fin
----
 # CL wonders why they're decoding an extra null string (eof ...).
----

RS agrees - using the canonical line reader code is simpler anyway:

 while {[gets $fin input] >= 0} {
       puts -nonewline stdout [::base64::decode $input]
 }