# IPv6 Compress and Expand

Canonicalise, expand and validate IPv6 addresses in bulk (up to 1,000). Compression follows RFC 5952 exactly: lowercase, no leading zeros, "::" replaces the longest run of zero groups (the first on a tie) and never a single group, and IPv4-mapped addresses keep a dotted ending. Expansion gives the 32-digit form, the leading-zero-free form, the ip6.arpa nibble form and binary. Prefixes, zone ids, [brackets]:port and URL hosts are preserved. Invalid input gets a precise error with a position.

**Not for:** Subnet math (use subnet_calculate) or finding the IPv4 inside an address (use ip_convert).

- Tool id: `ipv6-format`
- Category: ip
- Execution: pure
- MCP tool `ipv6_format` at https://lookupowl.com/mcp
- REST `GET https://lookupowl.com/api/v1/tools/ipv6-format` (or POST a JSON body)
- OpenAPI: https://lookupowl.com/api/openapi.json

## Input

| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| `addresses` | string | yes |  | One or more IPv6 addresses, one per line (commas and spaces also separate), up to 1,000. Prefix lengths (/64), zone ids (%eth0), [brackets] with :port and URL hosts (http://[2001:db8::1]:8080/) are accepted and kept. max length 65536 |
| `style` | "all" \| "compressed" \| "expanded" | no | `"all"` | compressed returns only the RFC 5952 form, expanded only the full forms, all returns everything. |

## Output

Results are wrapped in an envelope: `tool`, `version`, `requestId`, `data`, `summary`, `meta` (cache status, timing), `permalink`. `data` has these fields:

| Field | Type | Description |
|---|---|---|
| `items` | object[] |  |
| `totals` | object |  |
| `truncated` | boolean |  |

## Examples

### Compress a long address

```json
{"addresses":"2001:0db8:0000:0000:0000:ff00:0042:8329","style":"compressed"}
```

```bash
curl 'https://lookupowl.com/api/v1/tools/ipv6-format?addresses=2001%3A0db8%3A0000%3A0000%3A0000%3Aff00%3A0042%3A8329&style=compressed'
```

Web page: https://lookupowl.com/ipv6-compress?q=2001%3A0db8%3A0000%3A0000%3A0000%3Aff00%3A0042%3A8329

### Expand a short address

```json
{"addresses":"2001:db8::ff00:42:8329","style":"expanded"}
```

```bash
curl 'https://lookupowl.com/api/v1/tools/ipv6-format?addresses=2001%3Adb8%3A%3Aff00%3A42%3A8329&style=expanded'
```

Web page: https://lookupowl.com/ipv6-expand?q=2001%3Adb8%3A%3Aff00%3A42%3A8329

### RFC 5952 edge cases

```json
{"addresses":"2001:db8:0:0:1:0:0:1\n2001:0:0:1:0:0:0:1\n::ffff:102:304\n[FE80::1%eth0]:443","style":"all"}
```

```bash
curl 'https://lookupowl.com/api/v1/tools/ipv6-format?addresses=2001%3Adb8%3A0%3A0%3A1%3A0%3A0%3A1%0A2001%3A0%3A0%3A1%3A0%3A0%3A0%3A1%0A%3A%3Affff%3A102%3A304%0A%5BFE80%3A%3A1%25eth0%5D%3A443&style=all'
```

Web page: https://lookupowl.com/ipv6-compress?q=2001%3Adb8%3A0%3A0%3A1%3A0%3A0%3A1%0A2001%3A0%3A0%3A1%3A0%3A0%3A0%3A1%0A%3A%3Affff%3A102%3A304%0A%5BFE80%3A%3A1%25eth0%5D%3A443

## Web pages

- https://lookupowl.com/ipv6-compress
- https://lookupowl.com/ipv6-expand

## Limits and caching

- Cost: 1 unit for a live lookup, 1 unit for a cached one. Budgets are per network and published in the `RateLimit` response headers.
- Cache: results are kept for 86400 s.
- Timeout: 1 s.

## Related tools

- [IP Subnet Calculator](https://lookupowl.com/tools/subnet-calculator.md): Network, broadcast, usable range, masks and exact host counts for any IPv4 or IPv6 subnet.
- [IP Address Converter](https://lookupowl.com/tools/ip-convert.md): Convert IP addresses to decimal, hex and binary, IPv4 to IPv6 forms, and pull the IPv4 out of an IPv6 address.
- [CIDR / IP Range Converter](https://lookupowl.com/tools/ip-range-convert.md): Turn CIDR blocks into first/last addresses, and IP ranges into the minimal list of CIDR blocks.
- [Reverse DNS Lookup](https://lookupowl.com/tools/reverse-dns.md): Find the host name (PTR record) of an IPv4 or IPv6 address and check that it resolves back to the same address.

## Guide: IPv6 address compressor

Shorten an IPv6 address to its one canonical form, as RFC 5952 defines it.

### What compression does

Compression writes an IPv6 address in its shortest standard form. Drop the leading zeros in each group, then replace the longest run of all-zero groups with `::`. That turns `2001:0db8:0000:0000:0000:ff00:0042:8329` into `2001:db8::ff00:42:8329`. An IPv6 address has eight groups of four hex digits, and several short forms of the same address are legal. RFC 5952 picks one, so logs, databases and people agree on a single text for each address.

### How to use it

1. **Paste addresses**: One per line, up to 1,000 (commas and spaces also separate them). Prefix lengths (`/64`), zone IDs (`%eth0`, which name a network interface), square brackets with a port and URL hosts are accepted and left in place around the address.
2. **Copy the canonical form**: One address shows its short form and whether it was already canonical, with the first reason it changed. The JSON lists every change. Several addresses go into a table next to what you typed.
3. **Use it for comparisons**: Normalise addresses before you compare, deduplicate or store them as text. Two strings are the same address only if their canonical forms match.

> **From an AI assistant** Connect the LookupOwl MCP server and ask: “Give me the RFC 5952 form of 2001:0db8:0000:0000:0000:ff00:0042:8329.” The assistant calls `ipv6_format`, so nobody has to count zero groups by eye, and gets `2001:db8::ff00:42:8329` back with the rules that changed it. A pasted batch of addresses from a log is normalised in the same call.

### The RFC 5952 rules

1. **Leading zeros** in a group are removed, but a group of all zeros is written as a single `0`.
2. `::` replaces the **longest run** of consecutive zero groups, and appears **at most once**.
3. If two runs tie, the **first** is replaced.
4. `::` is **never used for a single** zero group. Write `0` instead.
5. Hex digits are **lowercase**.

| Input | Canonical | Why |
|---|---|---|
| `2001:0DB8:0000:0000:0000:FF00:0042:8329` | `2001:db8::ff00:42:8329` | Lowercase, leading zeros dropped, longest run compressed |
| `2001:db8:0:0:1:0:0:1` | `2001:db8::1:0:0:1` | Two equal runs: the first one wins |
| `2001:0:0:1:0:0:0:1` | `2001:0:0:1::1` | The longer run (three groups) wins |
| `2001:db8:0:1:1:1:1:1` | `2001:db8:0:1:1:1:1:1` | A single zero group is not compressed |
| `::ffff:102:304` | `::ffff:1.2.3.4` | Special case: IPv4-mapped addresses keep a dotted ending |

The last row follows RFC 5952 section 5, which recommends a dotted ending for addresses that carry an IPv4 address behind a well-known prefix. This tool applies it to IPv4-mapped addresses only (an IPv4 address carried inside an IPv6 one), as Go and recent versions of Python do. Every other address is written in hex. The all-hex spelling of a mapped address is shown under Other forms and in the JSON as `compressedHex`.

### Why other tools disagree

- **Older software compresses the first run, not the longest.** Libraries and devices written before RFC 5952 (2010) can produce valid but non-canonical text, for example `2001:0:0:1:0:0:0:1` written as `2001::1:0:0:0:1` instead of `2001:0:0:1::1`.
- **A single zero group compressed.** Some tools write `2001:db8::1:1:1:1:1` for an address with one zero group. It is valid, but RFC 5952 forbids it.
- **Uppercase hex.** Legal when you type it, but not canonical in output.
- **Invalid input.** More than one `::`, a group longer than four digits, more than eight groups or a stray character gets an error that says what is wrong, and where when it can.
- **Dotted endings.** Only IPv4-mapped addresses keep one. Anything else with a dotted tail, such as `64:ff9b::8.8.8.8`, comes out in hex as `64:ff9b::808:808`.

> **Searching logs** If different tools wrote your logs, one address can appear in several spellings, and a search for one spelling misses the rest. Normalise the addresses first, then search. The [expanded form](https://lookupowl.com/ipv6-expand) is the other fixed spelling worth searching for.

### How the compressor works

The address is parsed into eight 16-bit values, validated, and written out again by the five rules above. Finding the longest run of zero groups takes a single pass. The conversion runs on our server. The addresses are not written to logs and are held in memory for at most a day. On the website, Google Analytics also records what you enter, as the [privacy policy](https://lookupowl.com/privacy) explains.

The standards are **RFC 4291** section 2.2 (the text forms of an address) and **RFC 5952** (the recommended representation). Zone IDs come from **RFC 4007**, and square brackets around an address in a URL from **RFC 3986**.

### Frequently asked questions

**How do I shorten an IPv6 address?**

Drop the leading zeros in each group, then replace the longest run of all-zero groups with `::`. For example, `2001:0db8:0000:0000:0000:0000:0000:0001` becomes `2001:db8::1`. Write the hex digits in lowercase too. The tool applies the standard rules to every address you paste and shows the result.

**Can I use :: more than once?**

No, an address can contain `::` only once. Two double colons would make the address ambiguous, because nobody could tell how many zero groups each one stands for. If an address has two separate runs of zeros, only the longest is replaced and the other keeps its zeros.

**Why is my address not compressed further?**

Either it has no run of two or more zero groups, or it is already canonical. A single zero group is written as `0` and never as `::`, so `2001:db8:0:1:1:1:1:1` stays as it is. The tool marks addresses that need no change.

**Are 2001:db8::1 and 2001:0db8:0:0:0:0:0:1 the same address?**

Yes. They are two ways of writing the same 128-bit number, and every network stack treats them as one address. The trouble starts in text: a plain string comparison, a database lookup or a log search sees two different strings. Store and compare the canonical form and the problem goes away.

**Does it keep a port or prefix?**

Yes. Prefix lengths, zone IDs, brackets with ports and URL hosts are kept around the compressed address, and only the address itself is rewritten. For example, `[2001:DB8:0:0:0:0:0:1]:8080` becomes `[2001:db8::1]:8080`, and `2001:0db8:0:0:0:0:0:1/64` becomes `2001:db8::1/64`. You can paste a whole URL or a prefix and get it back tidied.

**Why does ::ffff:1.2.3.4 still have dots in it?**

It is an IPv4-mapped address, and RFC 5952 section 5 recommends a dotted ending for addresses like it, so this tool keeps one. The all-hex spelling, `::ffff:102:304`, is the same address. Other addresses that you type with a dotted ending are written out in hex.

**How do I expand a compressed address?**

Use the [IPv6 expand tool](https://lookupowl.com/ipv6-expand), which writes out all 32 hex digits again. It also gives you the form without leading zeros, the binary form and the `ip6.arpa` name that reverse DNS uses, so it is handy for sorting, comparing and building PTR records.

**Are the addresses I paste stored anywhere?**

Not in our logs. The compression runs on our server, whether you use the web page, the API or an AI assistant, and the addresses are held in memory for at most a day. On the website, Google Analytics also records what you enter. The [privacy policy](https://lookupowl.com/privacy) has the details.
