> For the complete documentation index, see [llms.txt](https://alham-rizvi.gitbook.io/alhamrizvi/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://alham-rizvi.gitbook.io/alhamrizvi/cryptography/hashing/26.-base32.md).

# Base32 Encoding

## What is Base32?

**Base32** is a binary-to-text encoding that uses 32 printable ASCII characters. It is designed for systems that are **case-insensitive** or need to avoid confusable characters. It trades compactness for readability and compatibility.

***

## Base32 Alphabet

### RFC 4648 Standard (Most Common)

```
A=0  B=1  C=2  D=3  E=4  F=5  G=6  H=7
I=8  J=9  K=10 L=11 M=12 N=13 O=14 P=15
Q=16 R=17 S=18 T=19 U=20 V=21 W=22 X=23
Y=24 Z=25 2=26 3=27 4=28 5=29 6=30 7=31
= (padding)
```

### Base32 Hex Alphabet (RFC 4648)

```
0-9, A-V  (avoids I, L, O, U to reduce visual confusion)
```

### Crockford Base32 (Human-friendly)

```
0-9, A-Z (excludes I, L, O, U)
Case-insensitive, allows hyphens
```

***

## How Base32 Works

Every **5 bytes** → **8 Base32 characters** (each character = 5 bits):

```
Input:   M          a          n
Binary:  01001101   01100001   01101110
Group in 5-bit chunks:
         01001  10101  10000  10110  1110x  xxxxx
         ↓      ↓      ↓      ↓      ↓
         J      V      Q      W      4  (+ padding)
```

### Padding

Base32 pads to a multiple of 8 characters using `=`:

```
1 byte  → 2 chars + 6 padding = "YQ======"
2 bytes → 4 chars + 4 padding = "YQQQ===="
3 bytes → 5 chars + 3 padding = "YQQQQ==="
4 bytes → 7 chars + 1 padding = "YQQQQQQ="
5 bytes → 8 chars + 0 padding = "YQQQQQQQ"
```

***

## Size Expansion

```
Every 5 bytes → 8 characters
Overhead: 8/5 = 60% size increase

Formula: ceil(n / 5) × 8 characters
```

| Input    | Bytes | Base32      |
| -------- | ----- | ----------- |
| 5 bytes  | 5     | 8 chars     |
| 10 bytes | 10    | 16 chars    |
| 20 bytes | 20    | 32 chars    |
| 1 KB     | 1024  | 1,640 chars |

***

## Implementation Examples

### Python

```python
import base64

data = b"Hello"

# Standard Base32
encoded = base64.b32encode(data)
print(encoded)  # b'JBSWY3DP'

decoded = base64.b32decode(encoded)
print(decoded)  # b'Hello'

# Case-insensitive decode
decoded = base64.b32decode("jbswy3dp", casefold=True)

# Hex Base32
hex_encoded = base64.b32hexencode(data)
hex_decoded = base64.b32hexdecode(hex_encoded)
```

### JavaScript

```javascript
// No built-in — use a library
// npm install hi-base32
const base32 = require('hi-base32');

const encoded = base32.encode("Hello");     // "JBSWY3DP"
const decoded = base32.decode("JBSWY3DP"); // "Hello"

// For binary data
const encodedBytes = base32.encode(new Uint8Array([72, 101, 108, 108, 111]));
```

### Go

```go
import "encoding/base32"

// Standard
encoded := base32.StdEncoding.EncodeToString([]byte("Hello"))
decoded, _ := base32.StdEncoding.DecodeString(encoded)

// Hex alphabet
hexEncoded := base32.HexEncoding.EncodeToString([]byte("Hello"))

// No padding
noPad := base32.StdEncoding.WithPadding(base32.NoPadding)
```

***

## Use Cases

### TOTP / 2FA Secret Keys

The most common real-world use of Base32:

```
Google Authenticator secret: JBSWY3DPEHPK3PXP
                             └── Base32-encoded 10-byte secret
```

```python
import pyotp, base64, os

# Generate TOTP secret
secret_bytes = os.urandom(10)
secret_b32 = base64.b32encode(secret_bytes).decode()

# Generate TOTP code
totp = pyotp.TOTP(secret_b32)
code = totp.now()  # "123456"

# Verify
is_valid = totp.verify("123456")
```

### DNS Names

```
Base32 is used in DNSSEC to encode binary hashes as valid DNS labels
(DNS labels are case-insensitive and alphanumeric)
```

### File Systems

```
Used in case-insensitive file system environments
Used in Tor .onion addresses (v2 used Base32)
```

### QR Code / User-Facing Codes

```
Crockford Base32 used for human-readable codes:
- No confusable chars (no I/1, O/0)
- Case-insensitive
- Example: "MXYPB-8ZT4Q" (product codes, serial numbers)
```

***

## Base32 vs Other Encodings

| Property       | Hex    | Base32   | Base64         |
| -------------- | ------ | -------- | -------------- |
| Alphabet size  | 16     | 32       | 64             |
| Size overhead  | 100%   | 60%      | 33%            |
| Case sensitive | No     | No       | Yes            |
| URL safe       | Yes    | Yes      | Variant needed |
| Human readable | High   | Medium   | Low            |
| Main use       | Hashes | 2FA, DNS | Files, JWTs    |

***

## Crockford Base32 (Human-Optimized)

```
0 1 2 3 4 5 6 7 8 9
A B C D E F G H J K
M N P Q R S T V W X
Y Z
```

* Excludes: I, L, O, U (visually confusing)
* Case-insensitive
* Allows hyphens as separators
* Used in: NanoID, ULID, some serial number systems

```python
# ULID (Universally Unique Lexicographically Sortable Identifier)
# uses Crockford Base32
import ulid
id = ulid.new()  # 01ARZ3NDEKTSV4RRFFQ69G5FAV
```

***

## Best Practices

* Use Base32 for **TOTP/2FA secrets** (canonical use case)
* Use **Crockford Base32** for human-facing identifiers
* Remove padding (`=`) for user-facing display
* Base32 strings are **safe for URLs** and DNS without escaping
* Always validate input before decoding


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://alham-rizvi.gitbook.io/alhamrizvi/cryptography/hashing/26.-base32.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
