8 March 2020

Base64 Encoding Options

Encoding binary data to Base64 is a common operation in the programming world. Simplest use case is probably to transport binary data over the network in common encoding so it doesn't get currupt while being processed by different systems. There are more use cases, some of them are also mentioned in examples bellow.

In this article we will go over the different encoding options provided in Apple's Foundation framework as part of the Data object.

Example Data

In the examples bellow, example data is encoded using base64EncodedString(options:) instance method on Data. Same options can be applied with base64EncodedData(options:).

To keep it simple, example data is one hundreed 1s generated like so:

let data = Data(repeating: 1, count: 100)

No Options - []

Default and most commonly used operation. Encodes data without any options and returns the result as a single line string.

Usage
data.base64EncodedString()
Result
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ==

Line Lengths

Line length options give us the posibility to limit the amount of characters before a line ending is inserted.

⚠️ Only one line length option should be provided, otherwise all options are ignored and the result is returned on a single line.

64 Characters - lineLength64Characters

Common use case of having line length limited to 64 characters is in the privacy-enhanced mail (PEM) standard which is nowadays mostly used to transport certificates and cryptographic keys over the network. You can read more about it in the Printable Encoding section of RFC 1421.

Usage
data.base64EncodedString(options: .lineLength64Characters)
Pretty Result
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
AQEBAQ==
Raw Result
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB\r\nAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB\r\nAQEBAQ==

Inserts a line ending in form of \r\n every 64 characters. We'll get to what \r\n means and how it can be modified in the Line Endings section.

76 Characters - lineLength76Characters

Common use case of 76 character line length is for Multipurpose Internet Mail Extensions (MIME) standard which is used to transport email messages. Check out the Base64 Content-Transfer-Encoding section of RFC 2045 for more information.

Usage
data.base64EncodedString(options: .lineLength76Characters)
Pretty Result
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ==
Raw Result
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB\r\nAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ==

Similar as lineLength64Characters, except a line ending is inserted every 76 characters.

Line Endings

Prerequisite for line ending options to have an effect is to pair them with one of the line length options, otherwise the result is a single line string and no line endings are inserted. By default all (two) line ending options are enabled as shown in Line Length examples.

The following examples use lineLength64Characters as a line length option. For that reason pretty results are not shown on a per option basis since they all look the same:

AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
AQEBAQ==

Carriage Return - endLineWithCarriageReturn

Carriage return - \r. Control character from the typewriter era that is somehow still around even though its purpose in the modern technology days seems questionable.

Usage
data.base64EncodedString(options: [.lineLength64Characters, .endLineWithCarriageReturn])
Raw Result
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB\rAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB\rAQEBAQ==

Line Feed - endLineWithLineFeed

Newline as most of us are familiar with: \n. Useful when dealing with cryptographic entities such as keys and certificates since they are mostly transported in PEM format which defines 64 character long lines separated by a line feed.

Usage
data.base64EncodedString(options: [.lineLength64Characters, .endLineWithLineFeed])
Raw Result
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB\nAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB\nAQEBAQ==

Share this article on Twitter. For any questions, comments or feedback reach out to me @hungrxyz.