An IPv4 address is represented inside an IPv6 structure by prefixing 80 zero bits, then 16 one bits written as FFFF, and appending the original 32-bit IPv4 value, producing the RFC 4291 IPv4-mapped form. That single 128-bit value is what you copy and paste into code, configuration files, logs, or documentation when you need the IPv4 peer written in IPv6 text. Doing this on Android means opening a browser-based converter, typing the dotted-decimal address, and choosing the output notation that matches the destination platform. The IPv4 to IPv6 Converter runs locally in your mobile browser and produces three equivalent spellings of the same bits: mixed dotted-decimal, compressed hexadecimal, and the fully expanded form. The mapping is purely a textual representation — it does not give the device native IPv6 connectivity, allocate a routable IPv6 address, or translate packets between protocols. It is the format used when an IPv6 socket, an API, or a configuration parser expects an IPv4 peer to be written as an IPv4-mapped IPv6 address.

The RFC 4291 IPv4-Mapped Format Explained
RFC 4291 section 2.5.5.2 defines the IPv4-mapped IPv6 address as a fixed 128-bit pattern: 80 zero bits, then 16 one bits, then the original 32-bit IPv4 address. The 16 one bits are written as the hexadecimal digits FFFF. The IPv4 octets are treated as the low-order 32 bits in network byte order, so the four octets 192.0.2.1 combine into the 16-bit hex words c000 and 0201, and the full 128-bit address becomes 0000:0000:0000:0000:0000:ffff:c000:0201. Every IPv4 address has exactly one IPv4-mapped IPv6 representation, and every valid IPv4-mapped IPv6 address decodes back to exactly one IPv4 address. Nothing about routing, prefix allocation, or address space changes during the conversion.
The practical reason for the form is that IPv6-sized data structures can carry an IPv4 peer when the surrounding code uses a 128-bit family. Socket APIs on Linux, BSD, Windows, and Android often expose an IPv4 connection inside an IPv6 sockaddr by returning an IPv4-mapped address. Log lines, allow-lists, and analytics pipelines that prefer IPv6 text use the mapped form to write a consistent 128-bit string. Whenever the destination platform uses Python's ipaddress.IPv6Address.ipv4_mapped, the C IN6_IS_ADDR_V4MAPPED macro, Java's Inet6Address when an IPv6 socket accepts an IPv4 peer, or Go's net.IP.To4 fallback, the mapped form is the value that survives the round-trip.
The Three Output Formats Compared
The converter writes three equivalent text forms. Each one carries the same 128 bits, which is critical for comparing parsed addresses instead of comparing raw strings.
| Notation | Example for 192.0.2.1 | When it fits |
|---|---|---|
| Mixed dotted-decimal | ::ffff:192.0.2.1 | Human-readable logs, configuration files, and documentation where readers recognise the IPv4 portion |
| Compressed hexadecimal | ::ffff:c000:201 | Compact form for code, JSON, and APIs that prefer canonical-style IPv6 text |
| Fully expanded hexadecimal | 0000:0000:0000:0000:0000:ffff:c000:0201 | Width-fixed columns, hex dumps, and audit trails where every 16-bit group must be visible |
Lowercase hexadecimal is used throughout. The three forms differ only in how the same bits are written; a parser that understands IPv6 text decodes each one back to the same address. That is why the converter exposes separate copy controls for each form: the destination platform dictates which spelling is safe to paste, and copying the wrong one is a common source of silent normalization bugs.
How to Convert an IPv4 Address to IPv6 on Android
- Open your mobile browser on the Android device and navigate to the IPv4 to IPv6 Converter page. The page runs locally, performs no network lookup, and stores nothing.
- Type the strict dotted-decimal IPv4 address into the input field. Use exactly four decimal octets from 0 to 255 with no spaces, no surrounding whitespace, no leading zeroes, no hexadecimal, no CIDR suffix, and no hostname. For example, enter 192.0.2.1, not 192.00.2.1 and not 192.0.2.1/32.
- Read the three output lines the converter renders: mixed notation ::ffff:192.0.2.1, compressed hexadecimal ::ffff:c000:201, and fully expanded 0000:0000:0000:0000:0000:ffff:c000:0201. Each row carries the same 128 bits.
- Choose the spelling that matches the destination platform. Use the mixed form when the consumer accepts dotted-decimal at the end. Use the compressed form for canonical-style IPv6 text. Use the expanded form when fixed-width columns or explicit 16-bit groups are required.
- Tap the copy control next to the chosen output and paste the value into the destination. Then ask the platform to parse and normalize it before relying on it for production configuration, policy, or comparison. Normalization means having the destination library round-trip the address into its canonical text before comparing against allow-lists or denylists.
- Run your test against the destination, not just the converter. Some frameworks silently rewrite the mixed form into a different equivalent spelling, and a string prefix check is not sufficient for authorization.
Strict Input Rules the Converter Enforces
The accepted input follows the same strict rules as Python's modern ipaddress library. Exactly four decimal octets, each from 0 to 255, with no surrounding whitespace, no signs, no shorthand, no hexadecimal notation, no CIDR suffix, and no leading zeroes. The value 192.00.2.1 is rejected because the leading zero in the second octet would indicate a legacy octal interpretation on some platforms. The value 192.0.2 is rejected because three octets are not a full IPv4 address. The value 192.0.2.1/32 is rejected because the CIDR suffix belongs to a subnet mask, not a host address. Hostnames are not resolved because DNS resolution introduces network dependence and the result can change over time; paste the numeric address you intend to represent and classify its scope separately if a policy distinguishes private, loopback, multicast, documentation, or globally reachable ranges.
Rejection of leading zeroes is the most important rule. A user who pastes 192.00.2.1 and the converter silently accepts it as 192.0.2.1 would lose the octal ambiguity guard, and the same digits would be interpreted differently on platforms that still honour octal. Eight built-in fixtures cover zero, one, private, loopback, documentation, and maximum IPv4 values, and the tests assert all three output forms plus invalid boundaries. Application code that consumes the converter's output should run the same checks before relying on the value, and the destination parser should be the final authority on whether the address is acceptable.
Mapped vs. NAT64, 6to4, and Native IPv6
The IPv4-mapped form is often confused with several transition mechanisms that share the same prefix letter but have different operational meaning. Picking the wrong one for a given job is a common source of configuration errors.
| Mechanism | Prefix or pattern | What it does |
|---|---|---|
| IPv4-mapped IPv6 (RFC 4291) | ::ffff:0:0/96 | Represents an IPv4 peer inside an IPv6-sized structure. No routing, no translation. |
| Deprecated IPv4-compatible (RFC 4291) | ::/96 with low 32 bits set | Deprecated by RFC 4291. Do not use for new deployments. |
| 6to4 (RFC 3056) | 2002::/16 | Automatic tunnel that wraps IPv6 in IPv4 for transition. Different prefix, different routing. |
| NAT64 (RFC 6146) | 64:ff9b::/96 by default | Translator that lets IPv6-only clients reach IPv4-only destinations. Different prefix, packet translation. |
| Native IPv6 assignment | Provider-allocated /48 or /64 | Routable IPv6 space from your ISP or internal allocator. The converter does not generate this. |
The converter deliberately emits only mapped addresses so a generic Convert button cannot silently choose a deployment mechanism. If the goal is subnet planning, native IPv6 assignment, or translation service configuration on the Android device or on the network it sits behind, use standards and tools designed for that separate task rather than treating the mapped representation as connectivity.
Using the Result in Android Code and Configuration
Android sockets are usually IPv6-capable when the device is in a dual-stack state. A Java ServerSocket bound to an IPv6 wildcard on the device can accept both IPv6 and IPv4 peers; the IPv4 peer is reported as an IPv4-mapped IPv6 address through Inet6Address. Likewise, Go's net.Listen with network = "tcp" on a dual-stack listener accepts IPv4 connections and resolves them through net.IP.To4. In both cases the mapped form is what the application code sees for the IPv4 peer, and the converter exists to produce that exact text from a known IPv4 address for documentation, test fixtures, or static configuration.
When the converter output is pasted into a configuration file, parse the value with a maintained library before applying policy. Treat the mapped form as semantically equivalent to the original IPv4 address for allow-lists, denylists, rate limits, and geo rules. A string prefix check on ::ffff: is not enough to recognize a mapped address; parse the address and ask the library whether the low 32 bits are a meaningful IPv4 peer. Compare parsed addresses or normalized canonical forms rather than raw text when equality matters, because systems may normalize the same bits to another equivalent spelling.
For production code, cross-check the converter's output with the destination platform's IP-address library and record whether the platform expects mapped addresses at all. If a downstream consumer instead expects a regular IPv6 address, an IPv6 subnet, or a NAT64 prefix, the IPv4-mapped form is the wrong value and the converter will not produce the right one. Python's IPv6Address.ipv4_mapped documentation shows the equivalent operation in code when you need to build the same value programmatically rather than copying it from a page.