Updated 2011-10-18 18:37:53 by BAS

Base64 is important 'cause it's used in MIME and by the Tk image commands.

From Tcl 8.6 onwards edit

The binary command includes a subcommand for working with base64-encoded data.
binary encode base64 ?-maxlen length? ?-wrapchar character? data
binary decode base64 ?-strict? data

Tcl 8.5 and before edit

There are several ways to do base64. Pure-Tcl Tcllib includes a base64 package. Trf is a handy C-coded extension which includes many encoding capabilities; among them is to replace the base64 encoding and decoding of tcllib with far faster versions. Jeff McWhirter, who's working on Tcl-coded Web-mail, has coded a small C object [1] just to do base64. (explain others)

The base64 which is part of tcllib is slow, and catastrophically memory-hungry for large (on the order of a megabyte or more) sources. The memory disaster results from what Donal Fellows reports as a bug to SourceForge [2]. He provided a patch as well [3]. Although it doesn't help performance significantly in the cases of interest to Cameron Laird, a simple fix for the memory woe is to overide base64::decode with a version which substitutes
    set length [string length $string]
    for {set ii 0} {$ii < $length} {incr ii} {
      set char [string range $string $ii $ii]
      ...  

for
    foreach char [split $string {}] {
      ...

Note: in the current version in tcllib (version 2.2.1 of base64), this code has been replaced by
    binary scan $string c* X  
    foreach x $X { 

Trf is a bit bulky (just as a base64 decoder, that is; as a way to do all the things it does, it's ideal).

Base 64 and a couple of hashing algorithms (md5, sha) could go into the Tcl core quite tinily. As far as Trf goes, I think I would rather see a nice wrapper for openssl.

'Nother base64 encoder/decoder uses Critcl, in a package called "ascenc", see [4].

See also: base58 Like base64, but without these characters: +/0OIl

BAS There's also a derivation on base64 commonly referred to as base64url, which essentially just makes the base64 encode string viable for inclusion as a query parameter in an URL. This is used in JWT. From what I understand, it replaces the + encoded char with - and the / with _, and with no = padding. So, I believe it would be something like (using Tcl 8.6 binary command):
  set base64url [string map {+ - / _ = ""} [binary encode base64 $string]] ;# untested

And of course, decoding would just be the reverse process.