Base45 Encoder and Decoder

Convert text, hex bytes or files to Base45 and back. Base45 uses the 45 characters of the QR code alphanumeric mode, so binary data fits into QR codes with little overhead.

Runs entirely in your browser. Nothing is uploaded.

How to use

  1. Choose Encode to turn text into Base45, or Decode to turn Base45 back into text or bytes.
  2. Type or paste your input, or open a file. Keep any spaces: they are part of the alphabet.
  3. When decoding binary data such as a certificate payload, switch the output to hex.
  4. Copy the result or download it as a file.

What is Base45?

Base45 is defined in RFC 9285. Its alphabet is the digits 0-9, the uppercase letters A-Z and nine symbols: space and $ % * + - . / :. These are exactly the 45 characters a QR code can store in its compact alphanumeric mode. Note that the space is a real character of the alphabet, not a separator.

The encoder takes the input two bytes at a time, reads them as a number from 0 to 65535 and writes that number as three Base45 digits, least significant digit first. A final single byte becomes two characters. As text, the result is 1.5 times the size of the input, larger than Base64.

Why Base45 suits QR codes

In alphanumeric mode a QR code packs two characters into 11 bits. Base64 cannot use that mode because it needs lowercase letters, so it falls back to byte mode with 8 bits per character, roughly 10.7 bits for every byte of data. Base45 needs only 8.25 bits per byte in alphanumeric mode, so the same data fits into a smaller QR code that is easier to scan.

When decoding, keep the spaces exactly as they are; only line breaks are ignored. Lowercase letters are not part of the alphabet and are reported as invalid.

Decoding EU Digital COVID Certificates

The QR codes of EU Digital COVID Certificates contain text that starts with HC1:. The rest is Base45: the certificate data is encoded as CBOR, signed with COSE, compressed with zlib and then Base45 encoded. To look inside:

  1. Remove the HC1: prefix. Its four characters are valid Base45, so leaving them in produces wrong bytes.
  2. Decode the rest here with hex output. zlib data usually starts with the byte 78.
  3. Decompress the bytes with zlib and parse the CBOR with another tool.

This tool handles only the Base45 step. It does not decompress the data, parse it or verify the signature.

Base45 in code

# Python (pip install base45)
import base45
base45.b45encode(b'AB')     # RFC 9285 example: BB8
base45.b45decode('BB8')     # b'AB'

Specification

Alphabet0-9 A-Z space $ % * + - . / :
Output size3 characters per 2 bytes (150%)
PaddingNone
StandardRFC 9285
Case sensitiveYes

Examples

Input (UTF-8)Output
Hello, World!%69 VDK2E:3404ESVDX0
Base64.isSH8LQEG%61*5P2
你好C-SEFK*.K

Frequently asked questions

Why does Base45 output contain spaces?

The space is one of the 45 characters of the alphabet, so it carries data. Do not trim or collapse spaces in Base45 text, or decoding will fail or give wrong bytes.

How do I decode an HC1: string?

Remove the HC1: prefix, decode the rest with hex output, then decompress the result with zlib and read the CBOR data with a separate tool. This tool performs only the Base45 step.

Is Base45 case sensitive?

Yes. Only uppercase letters belong to the alphabet, because the QR alphanumeric mode has no lowercase. Lowercase input is reported as invalid, together with its position.

Is Base45 more compact than Base64?

As plain text, no: Base45 is 1.5 times the input size and Base64 about 1.33 times. Inside a QR code, yes, because Base45 can use the denser alphanumeric mode.