UTF-8 Encoding

How text becomes bytes

UTF-8 is the character encoding used by almost every web page, file format and network protocol today. It stores each Unicode character as one to four bytes, and plain ASCII text stays exactly the same.

Convert text to UTF-8 online ↓

Unicode and encodings

Unicode assigns a number, called a code point, to every character: A is U+0041, ł is U+0142, € is U+20AC and the emoji 😀 is U+1F600. An encoding defines how these numbers are stored as bytes. UTF-8, designed by Ken Thompson and Rob Pike in 1992, is the most common one; others are UTF-16 and UTF-32.

How UTF-8 works

The number of bytes depends on the size of the code point. The first byte says how many bytes follow; every following byte starts with the bits 10:

Code pointsBytesBit pattern
U+0000 – U+007F10xxxxxxx
U+0080 – U+07FF2110xxxxx 10xxxxxx
U+0800 – U+FFFF31110xxxx 10xxxxxx 10xxxxxx
U+10000 – U+10FFFF411110xxx 10xxxxxx 10xxxxxx 10xxxxxx

For example, ł (U+0142, binary 101 0100 0010) needs two bytes: the bits are split into 00101 and 000010, giving 11000101 10000010, that is C5 82 in hexadecimal. The euro sign is E2 82 AC and 😀 is F0 9F 98 80.

Why UTF-8 won

  • ASCII compatible: English text and source code look the same as in ASCII.
  • Self-synchronising: a reader can find the start of the next character from any position, because continuation bytes always start with 10.
  • No byte order problems: unlike UTF-16, UTF-8 is a sequence of single bytes, so no byte order mark (BOM) is needed.

Not every byte sequence is valid UTF-8. Decoders must reject, for example, a lone continuation byte, a truncated sequence or an "overlong" encoding (such as C0 AF for /). Accepting overlong forms has led to real security holes, because filters checking for / or .. did not recognise them.

UTF-8 converter

Direction
Byte format
When decoding, enter the bytes in the selected format (space- or comma-separated; HTML entities look like Ä).

UTF-8 in practice

HTML pages declare it with <meta charset="utf-8">. In JavaScript, new TextEncoder().encode(text) returns the UTF-8 bytes of a string and new TextDecoder('utf-8', { fatal: true }) decodes them, throwing an error on invalid input – the tool above works this way. Python offers text.encode('utf-8') and data.decode('utf-8').

Encodings matter in cryptography too: ciphers and hash functions work on bytes, not characters, so the same text encoded differently gives a different ciphertext or hash. See also binary numbers and notation of numbers.