Base64
From Wikipedia, the free encyclopedia
Numeral systems by culture | |
---|---|
Hindu-Arabic numerals | |
Western Arabic Eastern Arabic Khmer |
Indian family Brahmi Thai |
East Asian numerals | |
Chinese Japanese |
Korean |
Alphabetic numerals | |
Abjad Armenian Cyrillic Ge'ez |
Hebrew Ionian/Greek Sanskrit |
Other systems | |
Attic Etruscan Roman |
Babylonian Egyptian Mayan |
List of numeral system topics | |
Positional systems by base | |
Decimal (10) | |
2, 4, 8, 16, 32, 64, 128 | |
3, 9, 12, 24, 30, 36, 60, more… | |
Base 64 or quadrosexagesimal is a positional notation using a base of 64. It is the largest power-of-two base that can be represented using only printable ASCII characters. This has led to its use as a transfer encoding for e-mail among other things. All well-known variants that are known by the name Base64 use the characters A–Z, a–z, and 0–9 in that order for the first 62 digits but the symbols chosen for the last two digits vary considerably between different systems. Several other encoding methods such as uuencode and later versions of binhex use a different set of 64 characters to represent 6 binary digits, but these are never called by the name Base64.
Contents |
[edit] Base 64 Encoding Schemes
[edit] Privacy-Enhanced Mail (PEM)
The first known use of Base 64 encoding for electronic data transfer was the Privacy-enhanced Electronic Mail (PEM) protocol, proposed by RFC 989 in 1987. PEM defines a "printable encoding" scheme that uses Base 64 encoding to transform an arbitrary sequence of octets to a format that can be expressed in short lines of 7-bit characters, as required by transfer protocols such as SMTP.
The current version of PEM (specified in RFC 1421) uses a 64-character alphabet consisting of upper- and lower-case Roman alphabet characters (A–Z, a–z), the numerals (0–9), and the "+" and "/" symbols. The "=" symbol is also used as a special suffix code. The original specification, RFC 989, additionally used the "*" symbol to delimit encoded but unencrypted data within the output stream.
To convert data to PEM printable encoding, the first byte is placed in the most significant eight bits of a 24-bit buffer, the next in the middle eight, and the third in the least significant eight bits. If there are fewer than three bytes left to encode (or in total), the remaining buffer bits will be zero. The buffer is then used, six bits at a time, most significant first, as indices into the string: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
, and the indicated character is output.
The process is repeated on the remaining data until less than four octets remain. If three octets remain, they are processed normally. If fewer than three octets (24 bits) are remaining to encode, the input data is right-padded with zero bits to form an integral multiple of six bits.
After encoding padded data, if two octets were remaining to encode, one "=" character is appended to the output; if one octet was remaining, two "=" characters are appended. This signals the decoder that the zero bits added due to padding should not be emitted in the reconstructed data.
PEM requires that all encoded lines consist of exactly 64 printable characters, with the exception of the last line, which may contain fewer printable characters. Lines are delimited by whitespace characters according to local (platform-specific) conventions.
[edit] MIME
The MIME (Multipurpose Internet Mail Extensions) specification, defined in RFC 2045, lists "base64" as one of several binary to text encoding schemes. MIME's base64 encoding is based on that of the RFC 1421 version of PEM: it uses the same 64-character alphabet and encoding mechanism as PEM, and uses the "=" symbol for output padding in the same way.
MIME does not specify a fixed length for base64-encoded lines, but it does specify a maximum length of 76 characters. Additionally it specifies that any extra-alphabetic characters must be ignored by a compliant decoder, although most implementations use a CR/LF
newline pair to delimit encoded lines.
Thus, the actual length of MIME-compliant base64-encoded data is usually about 140% of the original data length.
[edit] UTF-7
UTF-7, described in RFC 2152, introduced a system called Modified Base64. This data encoding scheme is used to encode UTF-16 as ASCII characters for use in 7-bit transports such as SMTP. It is a variant of the base64 encoding used in MIME.
The "Modified Base64" alphabet consists of the MIME base64 alphabet, but does not use the "=" padding character. UTF-7 is intended for use in mail headers (defined in RFC 2047), and the "=" character is reserved in that context as the escape character for "quoted-printable" encoding. Modified base64 simply omits the padding and ends immediately after the last BASE64 digit containing usefull bits (leaving 0-4 unused bits in the last base64 digit)
[edit] OpenPGP
OpenPGP, described in RFC 2440, describes Radix-64 encoding, also known as "ASCII Armor". Radix-64 is identical to the "base64" encoding described from MIME, with the addition of a 24-bit CRC checksum. The checksum is calculated on the input data before encoding; the checksum is then encoded with the same base64 algorithm and concatenated to the output data.
[edit] IRCu
In the P10 server-server protocol used by the IRCu IRC daemon and compatible software, a version of Base 64 encoding is used to encode client/server numerics and binary IP addresses. Client and server numerics have fixed sizes which match up with an exact number of base64 digits so no padding is needed. Binary IP addresses have leading zero bits added to make them fit. The symbol set is slightly different from the MIME alphabet, using [] instead of +/ to avoid clashes with other parts of the protocol that uses + internally as a marker to begin user modes.
[edit] RFC 3548
RFC 3548 (The Base16, Base32, and Base64 Data Encodings) is an informational (non-normative) memo that attempts to unify the RFC 1421 and RFC 2045 specifications of base64 encodings, alternative-alphabet encodings, and the seldom-used Base 32 and Base 16 encodings.
RFC 3548 forbids implementations from adding non-alphabetic characters unless they are written to a specification that refers to RFC 3548 and specifically requires otherwise; it also declares that decoder implementations must reject data that contains non-alphabetic characters unless they are written to a specification that refers to RFC 3548 and specifically requires otherwise.
[edit] RFC 4648
This RFC obsoletes RFC 3548 and focusses on base 64/32/16:
- This document describes the commonly used base 64, base 32, and base 16 encoding schemes. It also discusses the use of line-feeds in encoded data, use of padding in encoded data, use of non-alphabet characters in encoded data, use of different encoding alphabets, and canonical encodings.
[edit] Example
A quote from Thomas Hobbes's Leviathan:
- Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.
is encoded in MIME's base64 scheme as follows:
TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=
In the above quote the encoded value of Man is TWFu. Encoded in ASCII, M, a, n are stored as the bytes 77
, 97
, 110
, which are to say, 01001101
, 01100001
, 01101110
in base 2.
Now from these three bytes joined together, we get the 24 bit buffer, which would be 010011010110000101101110
. This number has to be converted to its base 64 value, which can be done by taking packs of 6 bits at a time (6 bits has a maximum of 64 different binary values). Now taking 6 bits at a time from the buffer, we get the 4 numbers (24 = 6x4), which are then converted to their corresponding values in Base 64.
Text content | M | a | n | |||||||||||||||||||||
ASCII | 77 | 97 | 110 | |||||||||||||||||||||
Bit pattern | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | 1 | 0 |
Index | 19 | 22 | 5 | 46 | ||||||||||||||||||||
Base64-Encoded | T | W | F | u |
Hence, 3 uncoded bytes (in this case, ASCII characters) come in, and 4 encoded ASCII characters come out.
To illustrate the padding, as we shorten the input, the output changes as follows:
Input ends with carnal pleasure. Output ends with: c3VyZS4= Input ends with carnal pleasure Output ends with: c3VyZQ== Input ends with carnal pleasur Output ends with: c3Vy Input ends with carnal pleasu Output ends with: c3U=
[edit] URL Applications
Base64 encoding can be helpful when fairly lengthy identifying information is used in an HTTP environment. Hibernate, a database persistence framework for Java objects, uses Base64 encoding to encode a relatively large unique id (generally 128-bit UUIDs) into a string for use as an HTTP parameter in HTTP forms or HTTP GET URLs. Also, many applications need to encode binary data in a way that is convenient for inclusion in URLs, including in hidden web form fields, and Base64 is a convenient encoding to render them in not only a compact way, but in a relatively unreadable one when trying to obscure the nature of data from a casual human observer.
Using a URL-encoder on standard Base64, however, is inconvenient as it will translate the '+' and '/' characters into special '%XX' hexadecimal sequences ('+' = '%2B' and '/' = '%2F'). When this is later used with database storage or across heterogeneous systems, they will themselves choke on the '%' character generated by URL-encoders (because the '%' character is also used in ANSI SQL as a wildcard).
For this reason, a modified Base64 for URL variant exists, where no padding '=' will be used, and the '+' and '/' characters of standard Base64 are respectively replaced by '*' and '-', so that using URL encoders/decoders is no longer necessary and has no impact on the length of the encoded value, leaving the same encoded form intact for use in relational databases, web forms, and object identifiers in general.
Another variant called modified Base64 for regexps uses '!-' instead of '*-' to replace the standard Base64 '+/', because both '+' and '*' may be reserved for regular expressions (note that '[]' used in the IRCu variant above would not work in that context).
There are other variants that use '_-' or '._' when the Base64 variant string must be used within valid identifiers for programs, or '.-' for use in XML name tokens (Nmtoken), or even '_:' for use in more restricted XML identifiers (Name).
[edit] Other applications
Base64 can be used in a variety of contexts:
- Thunderbird and Evolution both use Base64 to obscure e-mail passwords
- Base64 is often used as a quick but insecure shortcut to obscure secrets without incurring the overhead of cryptographic key management
- Spammers use Base64 to evade basic anti-spam tools, which often do not decode Base64 and therefore cannot detect keywords in encoded messages.
- Base64 is used to encode character strings in LDIF files
- Base64 is sometimes used to embed binary data in an XML file, using a syntax similar to <data encoding="base64">......</data> e.g.: Firefox's bookmarks.html.
[edit] See also
[edit] External links
- RFC 989 (Privacy Enhancement for Electronic Internet Mail) (obsolete)
- RFC 1421 (Privacy Enhancement for Electronic Internet Mail)
- RFC 2045 (Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies)
- RFC 3548 (The Base16, Base32, and Base64 Data Encodings)
- RFC 4648 (The Base16, Base32, and Base64 Data Encodings)
- Base64 encoder/decoder web-based platform-independent encoder/decoder (GPL, with source code)
- Base64 Decoder with graphical user interface (Windows)
- Home of the Base64 specification, with an online decoder and C99 implementation
- b64: Base-64 Encoding Library (C library with C++ mapping; Platform-independent)
- Base64 source code in C
- Base64 in C/C++ with 2-3x faster encode/decode
- Base64 in C, using Vstr, colorized using simple 24bit conversion
- Base64 source code in Java / Another Java source code
- Base64 implementation in JavaScript
- MIME::Base64 Perl module
- Firefox extension that supports ASCII/Base64 conversions
- emacs functions for Base64 conversions
- Base64 article at TenMinuteTutor.com
- Visual FoxPro functions for Base64 conversions
- Base64 decoder and encoder online
- Video playback using Base64-encode Data URIs in XML format
- T-SQL implementation