Qoyod
Pricing

Knowledge Base

Base64 Encoding in the Electronic Invoice

When you issue an electronic invoice in Saudi Arabia, the QR code on the invoice carries a long string of letters and numbers that looks meaningless at first glance: something like AQ1mYXR1cmEgQVNQ.... This string is not random, nor is it human-readable text. It is binary data that has been converted into safe, transportable text through an encoding called Base64. This encoding is the bridge that allows precise technical data, such as the hash, the cryptographic stamp, and the QR code content, to be carried inside text and XML files without corruption.

In this technical guide we focus on Base64 alone: what it is, why we need it in the first place, how its 64-symbol alphabet is formed, how it converts binary data into text, and the role of padding. We also explain exactly where Base64 appears within electronic invoicing in Saudi Arabia, and walk through a complete step-by-step encoding example. The structure of the QR payload in TLV encoding is detailed in the guide «TLV», and the QR code fields themselves in the guide «QR Structure». Here the focus is on the encoding mechanism itself and its behavior on the data.

What is Base64 encoding?

Base64 is a system for representing binary data in a text format that relies on just 64 symbols from the printable ASCII characters. The idea is simple at its core: you take raw data made up of bytes, and re-express it using a limited, safe set of letters and numbers that travel safely through any text medium, whether an XML file, an email message, or a field inside a database.

The term itself describes how it works: “Base” refers to the numeric base, and “64” refers to the number of available symbols. Just as the decimal system uses ten digits (0 to 9), and the hexadecimal system uses sixteen symbols, Base64 uses sixty-four symbols to express data. Each of these sixty-four symbols represents six bits of the original data.

It is important to realize that Base64 is not encryption and not compression. It is encoding only. Encoding is a fully reversible operation with no secret key: any party holding the encoded string can decode it and recover the original data. Base64 therefore adds no confidentiality protection. Its sole function is to make binary data transportable in a text environment without being corrupted.

The difference between encoding, encryption, and compression

Many people confuse these three concepts because they all transform the shape of the data. But the purpose is entirely different in each case, and confusing them leads to errors in design and implementation.

Encryption converts data into a form that only someone holding the secret key can read, and its purpose is to protect confidentiality. Compression reduces the size of data by removing redundancy, and its purpose is to save space and bandwidth. Encoding, by contrast, re-represents the data with a different set of symbols, with no key and no size reduction, and its sole purpose is to ensure correct transport across a given medium. Base64 is therefore pure encoding: it neither hides the data nor shrinks it, but makes it fit to travel through a text environment.

Confusing these concepts is a common mistake that leads to mistaken expectations. Anyone who thinks Base64 protects data builds an insecure system. And anyone who expects it to reduce size is surprised to find the output larger than the original. Understanding the correct purpose of each operation is a condition for using it in its proper place.

Why do we need Base64 in the first place?

Digital systems deal with two kinds of data: text data and binary data. Text data is made up of letters, numbers, and symbols understood by humans and systems alike. Binary data, on the other hand, is a raw sequence of bytes that may hold any value from 0 to 255, including values that have no printable text symbols at all.

The problem appears when transporting binary data across a channel designed for text. Many channels and formats, such as XML, JSON, email, and URLs, assume the content is clean text. If you inject raw binary bytes into them, you may hit a byte that matches a control character, or a symbol that carries a special meaning in that format, corrupting the file or causing it to be misinterpreted.

Take the invoice XML file as an example. The invoice cryptographic stamp is raw binary data. If you placed it as-is inside an XML element, it might contain a byte matching the “less-than” or “greater-than” sign or the quotation mark, which are symbols with a structural meaning in XML. At that point parsing of the file breaks. The solution is to convert the stamp into safe Base64 text, which contains only letters and numbers that do not conflict with the XML structure.

Here lies the practical value of Base64: it guarantees that binary data arrives intact across any text medium. Its alphabet is carefully chosen so that it contains no symbol carrying a special meaning in most common text formats. This makes it the standard choice for carrying attachments, keys, signatures, and hashes inside structured text files.

Imagine the invoice XML file as a pipe designed to carry text only. Raw binary data is like a fluid that may react with the pipe wall and damage it. Base64 wraps this fluid in a compatible text container, so it passes safely from end to end. This analogy explains why Base64 became a global standard adopted by invoicing, email, and digital-certificate systems alike.

The Base64 alphabet: the sixty-four symbols

The heart of the encoding is a fixed table of 64 symbols, known as the standard Base64 alphabet. Each value from 0 to 63 corresponds to a single symbol in this table. The standard alphabet, as defined by the RFC 4648standard, consists of four ordered groups.

The first group is the uppercase letters from A to Z, representing values 0 to 25. The second group is the lowercase letters from a to z, representing values 26 to 51. The third group is the digits from 0 to 9, representing values 52 to 61. As for the last two values, 62 and 63, they are represented by the symbols + and/ respectively.

Alongside these sixty-four symbols, there is one special symbol, the equals sign =, used for padding at the end of the string only, and it is not counted among the sixty-four because it represents no data. We explain its role in detail in the padding section.

The following table shows the complete alphabet map, where each number corresponds to the six-bit value carried by its symbol:

The Base64 alphabet
The sixty-four symbols used by Base64 encoding.
Base64 symbols

A–Z represent values 0–25

a–z represent values 26–51

0–9 represent values 52–61

The symbols + and / represent 62 and 63

The symbol = for padding

Every six bits are represented by a single symbol from this alphabet.

Note that the order of the symbols is not arbitrary but sequential and logical: uppercase letters first, then lowercase, then digits, then two extra symbols. This fixed order is what guarantees that every system in the world decodes the string the same way and obtains the same data. Any difference in the alphabet order means an entirely different string.

The standard alphabet versus the URL-safe alphabet

There is another variant of the alphabet called Base64URL, designed specifically to appear safely inside URLs and file names. The difference is limited to the last two symbols: this variant replaces the symbol + with the symbol , and the symbol / with the symbol _. The reason is that + and/ carry a special meaning inside URLs, so replacing them prevents the link from being corrupted.

In the context of electronic invoicing in Saudi Arabia, the alphabet used is the standard one, because Base64 values appear inside XML files and data fields, not inside URLs. The developer should therefore pay attention to the correct alphabet when encoding and decoding, because using the wrong alphabet produces a string that does not match what the Authority’s systems expect.

How does the encoding work step by step?

The central idea in Base64 is regrouping the bits. The original data is stored in bytes, and each byte is eight bits. But Base64 does not work in units of eight bits; it works in units of six bits, because six bits are enough to express 64 different values, which is exactly the size of the alphabet.

The process therefore begins by taking every three bytes of the original data together. Three bytes equal 24 bits. These twenty-four bits are then re-split into four groups, each of six bits. Each six-bit group gives a value from 0 to 63, which is translated into a single symbol from the Base64 alphabet. The result is that every three bytes turn into four symbols.

This fixed ratio, three bytes to four symbols, is why the encoded text is larger in size than the original. The amount of text data increases by about a third compared to the original binary data. This increase is the acceptable price for guaranteeing safe transport across text channels.

We summarize the encoding steps in a clear sequence:

  1. Split the original data into groups of three bytes each (24 bits).
  2. Rearrange the twenty-four bits into four groups of six bits each.
  3. Compute the decimal value of each six-bit group (from 0 to 63).
  4. Replace each value with its corresponding symbol in the Base64 alphabet.
  5. Add padding if the data is not exactly divisible by three bytes.
How Base64 encoding works
Converting three bytes into four text symbols.
1

3 bytes (24 bits)

2

Split into 4 groups of 6 bits

3

4 Base64 text symbols

Base64 converts binary data into text that is safe to transport in XML.

Why exactly three bytes?

Choosing three bytes as the processing unit is not arbitrary but the result of an elegant calculation. A byte is eight bits, and a Base64 symbol represents six bits. The least common multiple of eight and six is twenty-four. That is, twenty-four bits divide evenly into three bytes (3 × 8) on one hand, and into four six-bit symbols (4 × 6) on the other.

This match is what makes the conversion clean with no dangling bits when the data length is a multiple of three. But when the length is not a multiple of three, the need for padding appears, which is what we explain now.

Padding and the equals sign

Not all data is exactly divisible by three bytes. One or two bytes may remain in the last group. This is where padding steps in to preserve the fixed four-symbol structure of each group, even when the data is not enough to fill the last group.

The rule is simple. If two bytes (16 bits) remain in the last group, they produce three actual symbols, then a single equals sign = is added to complete the group to four symbols. And if only one byte (8 bits) remains in the last group, it produces two actual symbols, then two equals signs == are added to complete the group.

The equals sign does not represent data; it only indicates that the last group was incomplete. When decoding, the system understands from the number of equals signs how many actual bytes were in the last group, and ignores the extra bits. This guarantees the original data is recovered exactly, with no addition or omission.

The padding rule can be summarized in three cases:

  • Data length is a multiple of three: no padding, the string ends with four complete symbols.
  • Two bytes remain: the string ends with three symbols then a single equals sign =.
  • One byte remains: the string ends with two symbols then two equals signs ==.

This is why you often see Base64 strings ending with one or two equals signs. It is not an error or corruption, but an indication that the original data length was not a multiple of three. Whether padding is present or not does not change the recovered data; it is merely a mechanism to complete the structure.

A complete step-by-step encoding example

Let us apply the above to a short word. We will encode the English word Sun made up of three letters, that is, exactly three bytes, an ideal case that needs no padding.

Step one: we convert each letter to its value in the ASCII table, then to eight bits.

S  =  83  =  01010011
u  = 117  =  01110101
n  = 110  =  01101110

Step two: we place the twenty-four bits in a single continuous row with no separators.

01010011 01110101 01101110
=> 010100110111010101101110

Step three: we re-split the twenty-four bits into four groups of six bits each, then compute the decimal value of each group.

010100 110111 010101 101110
010100 = 20
110111 = 55
010101 = 21
101110 = 46

Step four: we translate each value into its symbol in the Base64 alphabet. The value 20 corresponds to U, the value 55 corresponds to 3, the value 21 corresponds to V, and the value 46 corresponds to u.

20 -> U
55 -> 3
21 -> V
46 -> u

"Sun"  =>  "U3Vu"

The result is that the word Sun is converted through Base64 into U3Vu. Note that the input is three bytes and the output is four symbols, exactly as the rule predicted, and no padding is needed because the length is a multiple of three.

If we encoded a four-letter word instead of three, one byte would remain in the last group, so two equals signs would appear at the end. And if it were five letters, two bytes would remain, so a single equals sign would appear. This is how the role of padding is manifested in practice in the length of the resulting string.

How does the reverse decoding work?

Decoding Base64 proceeds in the exact opposite direction. The system takes every four symbols from the string, converts each symbol to its decimal value using the same alphabet, then writes each value in six bits. The four values combine into twenty-four bits, which are re-read as three complete bytes. In this way the system recovers the original data byte by byte.

When padding is present, the system reads the number of equals signs at the end of the string. A single sign means the last group contains only two bytes, so it ignores the extra bits. Two signs mean only one byte. This symmetry between encoding and decoding is what guarantees that any system in the world reaches the very same original data without ambiguity, a property that is indispensable in electronic invoicing where two different parties verify the same value.

Where does Base64 appear in electronic invoicing in Saudi Arabia?

In the second phase of electronic invoicing, the Zakat, Tax and Customs Authority (ZATCA) imposes precise technical requirements that include multiple pieces of binary data. This data cannot be carried as-is inside text formats, so Base64 comes in to convert it into safe text. We review the main places where it appears.

Each of these positions combines two properties: the data in it is binary in origin, and it travels inside a text channel such as an XML file or a QR code. This is why the need for Base64 recurs everywhere that binary technical data meets a structured text format mandated by the Authority.

The QR code payload

The QR code on the simplified invoice carries a set of fields ordered in binary TLV format. This binary payload is encoded in full with Base64 to become a single text string, which is then converted into a QR code image. Any scanner reading the code reads the text string, then decodes Base64 to recover the binary fields and verify them. We detail the structure of these fields in the guide «TLV».

The hash value

The hash fingerprint produced by the SHA-256 algorithm is a 256-bit binary value. This value is written inside the invoice in Base64 encoding to be a compact text string instead of a long form. The value itself enters the invoice-chaining sequence. The details of the algorithm are in the guide «SHA-256», and the chaining mechanism in the guide «PIH».

The cryptographic stamp and the certificate

The cryptographic stamp of the invoice is binary data produced by the digital signature. Likewise the Cryptographic Stamp Identifier for the taxpayer (CSID) and the content of the associated digital certificate. All these values are represented in Base64 encoding to be written inside the invoice XML file according to the UBL 2.1 format without conflicting with the file structure. The XML file itself and its elements are detailed in the guide «XML Invoice».

The common denominator across all these positions is one: sensitive binary data that needs to travel through text formats, so Base64 plays the role of the safe bridge that carries it without corruption.

Where Base64 appears in the invoice
The positions where Base64 encoding is used.
Base64 positions

The QR code payload (after TLV)

The Previous Invoice Hash (PIH)

The cryptographic stamp and CSID certificate

The files embedded inside the document

Base64 is used whenever we need to carry binary data inside text.

Common mistakes when dealing with Base64

The first recurring mistake is choosing the wrong alphabet. Using the Base64URL alphabet where the Authority requires the standard alphabet produces a string that differs in the last two symbols, so it is rejected at verification. The rule is to check the required alphabet for each field before encoding.

The second mistake is neglecting or dropping the padding. Some libraries produce a string with no equals signs, which is acceptable in certain contexts but breaks verification when the other party expects full padding. Always verify that the encoding settings match between your system and what the Authority’s systems expect.

The third mistake is encoding an already-encoded value twice, or decoding a string on the assumption that it is plain text so meaningless symbols appear. Every Base64 value must be decoded once with the correct alphabet to return to its binary origin. Paying attention to the number of encoding passes and the state of the data before each operation avoids these mistakes.

What does this mean for the developer and the accountant?

For the developer building an integration with electronic invoicing, understanding Base64 is a condition for reading and writing the technical fields accurately. The common mistakes are known: using the URL-safe alphabet instead of the standard one, neglecting padding, or confusing encoding with encryption. Any of these mistakes produces a string that does not match what the Authority’s systems expect, so the invoice is rejected.

The accountant or business owner, on the other hand, needs to encode nothing manually. These technical details are handled automatically by the approved invoicing system. The value of understanding here appears in the ability to read the content of the electronic invoice and to know that the long strings in the QR code and the XML file are sound technical data, not an error or corruption.

Qoyod handles generating all these values with the correct encoding within the Phase Two-compliant electronic invoice issuance. The system generates the QR code with its encoded payload, computes the hash and writes it in Base64 encoding, and manages the cryptographic stamp and the certificate inside the XML file according to the UBL 2.1format, all without any manual intervention from the user.

Start today

Invoices compliant with Phase Two without technical complexity

Qoyod handles generating the QR code, the cryptographic stamp, and the hash with the correct encoding automatically, so your invoices are issued compliant with the Zakat, Tax and Customs Authority without you writing a single line of code.

Start your free trial and issue invoices compliant with the Authority

A practical summary

Base64 is an encoding that converts binary data into text that can be transported safely across text channels, using an alphabet of 64 symbols representing the values 0 to 63, with an equals sign for padding. It works by grouping every three bytes into 24 bits, then re-splitting them into four six-bit symbols, so the text size increases by about a third in exchange for guaranteeing transport integrity.

In electronic invoicing in Saudi Arabia, Base64 appears in the QR code payload, the hash value, the cryptographic stamp, and the certificate inside the XML file. It is neither encryption nor compression, but a safe text bridge for binary data. Once the developer understands its standard alphabet, the padding rule, and the difference between it and encryption, they can read and write the technical fields with an accuracy that matches the Authority’s requirements.

Guides

Continue your learning journey

Explore the rest of Qoyod’s guides, or start applying what you’ve learned.

Live webinars hosted by the Qoyod team to help you use the software easily and answer your questions.

Discover Qoyod’s latest updates, ongoing improvements, and new features in one place.

Our team is ready to help you and provide instant support for any issue you face, around the clock.