Base64 Encoding and Decoding
base64-encode
base64-decode
base64-encode-stream
base64-decode-stream
Bibliography
1.0

Base64 Encoding and Decoding

Ryan Culpepper <ryanc@racket-lang.org>

This library provides support for Base64 encoding and decoding, similar to net/base64 but with more options.

 (require base64) package: base64-lib

procedure

(base64-encode src    
  [#:endcodes endcodes    
  #:line line    
  #:line-end line-end    
  #:pad? pad?])  bytes?
  src : (or/c bytes? string? input-port?)
  endcodes : (or/c #f 'url bytes?) = #f
  line : (or/c #f exact-positive-integer?) = #f
  line-end : bytes? = #"\r\n"
  pad? : boolean? = (and line #t)
Encodes the bytes of src in Base64 (see [RFC 4648]), returning a byte string.

If endcodes is #f, the standard characters for the last two codes are used: #"+/". If endcodes is 'url, the alternate endcodes for URLs and filenames are used: #"-_" (see [RFC 4648], section 5). Otherwise, endcodes must be a byte string containing two bytes, and these are used as the last two codes for the encoding.

If line is a number, it must be a positive multiple of 4. In that case, the output is broken into segments whose length is line bytes (except possibly the final segment), and line-end is added to the end of each segment.

If pad? is #t, then the output is padded, using = characters, to a multiple of 4 bytes (disregarding line separators). If pad? is #f, the padding is omitted.

Examples:
> (base64-encode #"apple")

#"YXBwbGU"

> (base64-encode #"apple" #:pad? #t)

#"YXBwbGU="

> (base64-encode #"apple" #:line 8)

#"YXBwbGU=\r\n"

> (base64-encode "orange")

#"b3Jhbmdl"

> (base64-encode "orange" #:pad? #t)

#"b3Jhbmdl"

> (base64-encode "orange" #:line 8)

#"b3Jhbmdl\r\n"

> (base64-encode "apples or oranges")

#"YXBwbGVzIG9yIG9yYW5nZXM"

> (base64-encode "apples or oranges" #:line 8)

#"YXBwbGVz\r\nIG9yIG9y\r\nYW5nZXM=\r\n"

procedure

(base64-decode src    
  [#:endcodes endcodes    
  #:mode mode])  bytes?
  src : (or/c bytes? string? input-port?)
  endcodes : (or/c #f 'url bytes?) = #f
  mode : (or/c 'strict 'whitespace) = 'whitespace
Decodes the bytes of src as Base64, returning a byte string.

The endcodes are interpreted the same as for base64-encode.

If mode is 'strict, then the entire input must consist of Base64-encoded data, without padding and without whitespace or other extra characters. If mode is 'whitespace, then the input is divided into segments separated by whitespace and padding = characters; each segment is decoded independently, and the results are concatenated. (This correctly handles the concatenation of padded encodings. It is not equivalent to deleting padding and whitespace characters and then decoding what remains as a single segment.)

In either mode, if src contains any content that is not valid Base64-encodings, padding, or whitespace, then exn:fail:read is raised, with the location of the first illegal byte. If the length of a segment (not including whitespace or padding) is 1 (mod 4), then exn:fail:read is raised, with the location of the segment’s end. If the length of a segment is 2 or 3 (mod 4), then the unused bits in the final byte are ignored — that is, no error is raised if the unused bits are not all zero.

Examples:
> (base64-decode "YXBwbGU")

#"apple"

> (base64-decode "YXBw = \n=bGU")

#"apple"

> (base64-decode "YXB wbGU") ; different!

#"ap\301\261\224"

procedure

(base64-encode-stream src    
  dest    
  [#:endcodes endcodes    
  #:line line    
  #:line-end line-end    
  #:pad? pad?])  void?
  src : (or/c bytes? string? input-port?)
  dest : output-port?
  endcodes : (or/c #f 'url bytes?) = #f
  line : (or/c #f exact-positive-integer?) = #f
  line-end : bytes? = #"\r\n"
  pad? : boolean? = (and line #t)
Like base64-encode, but writes the output to dest.

procedure

(base64-decode-stream src    
  [#:endcodes endcodes    
  #:mode mode])  bytes?
  src : (or/c bytes? string? input-port?)
  endcodes : (or/c #f 'url bytes?) = #f
  mode : (or/c 'strict 'whitespace) = 'whitespace
Like base64-decode, but writes the output to dest.

Bibliography

[RFC 4648] “RFC 4648: The Base16, Base32, and Base64 Data Encodings.” https://tools.ietf.org/html/rfc4648