Bytes, hex and entities: the same text in four notations

The same five letters can be written five ways without changing a bit. Knowing which notation you are looking at is what stops a hex dump from being pasted into a text field as if it were text.

One string, four byte notations

“Hello” is five ASCII characters, so its UTF-8 bytes are also five. The same bytes can be printed in any base; measured with the converters on this site:

Notation“Hello”
Hex48 65 6C 6C 6F
Decimal72 101 108 108 111
Octal110 145 154 154 157
Binary01001000 01100101 01101100 01101100 01101111

Each is exact and reversible. The differences are formatting: hex uses two digits per byte, binary eight, octal three, decimal as a number. A decoder that strips spaces and reads pairs is doing hex; one that reads groups of eight is doing binary. Feeding one notation to the other's decoder produces plausible-looking nonsense rather than an error, which is why the label matters.

Bytes are not characters

For ASCII the byte count and the character count agree. For anything else they do not: é is two bytes in UTF-8, a Thai digit is three, and an emoji is four. A hex dump shows bytes, so a single accented letter appears as two pairs and a single emoji as four. Converting those bytes back as text is only valid if the encoding is known; the same bytes read as Latin-1 produce different characters.

The replacement character � (U+FFFD) is the decoder telling you the sequence is not valid UTF-8. It is not a failure of the tool — it is the honest answer that the bytes are not text in that encoding. Hex of a hash, a key or an encrypted blob will produce it, because those bytes were never text.

HTML entities: escaping, not encoding

An HTML entity is a way to write a character in HTML source so it cannot be confused with markup: &amp; is an ampersand, &lt; a less-than sign. Numeric forms &#38; and &#x26; refer to the same character by code point. Encoding text for HTML means replacing the characters that have syntactic meaning (&, <, >, quotes in attributes); decoding reverses that.

The classic bug is double escaping: text that already contains &amp; is escaped again to &amp;amp;, so the page displays &amp; instead of &. The rule is to encode once, at the boundary where text enters HTML, and to store the unencoded text rather than the entity form.

Entities in HTML and in URLs

HTML entities and percent-encoding are different escapes for different grammars. An entity belongs in HTML source and is decoded by the HTML parser; percent-encoding belongs in a URL and is decoded by the URL parser. Putting %26 in HTML text displays the literal characters, and putting &amp; in a URL does not escape an ampersand for the URL parser. Encode for the grammar the value is entering, once, at the boundary.

Numbers, endianness and Base64

Bytes only become text when you agree on an encoding. The four bytes 00 00 00 2A are the integer 42 in big-endian order, 704,643,072 in little-endian, and a NUL-prefixed string in UTF-8; the same bytes, three readings. A hex dump of a binary format is not text, and decoding it as UTF-8 produces replacement characters rather than a number. If the value is an integer, read it with the format's byte order, not with a text decoder.

Base64 is a fourth notation on top of bytes: it re-expresses them using 64 safe characters and adds about a third to the length. It is not encryption and it is not compression; it exists so binary can travel through text-only channels. A Base64 string of text is not the text's hex and is not its entity form — each notation answers a different question, and converting one to another through text usually means decoding to bytes first.

Full-width and superscript

Full-width forms are separate code points used in CJK typography to align Latin letters and digits with ideographs. They look like ASCII and are not: A is U+FF21, not U+0041. Converting to half-width is a code-point mapping, exact in both directions, and useful when a form rejects the full-width forms.

Superscript and subscript characters are Unicode characters with a raised or lowered appearance, not formatting. x² is x followed by U+00B2, which is why it survives a copy into a plain-text field and why a search for “x2” does not match it. They are presentation, and screen readers may read them as separate characters; for mathematical notation, HTML <sup> is the accessible choice.

Questions this guide raises

Is hex just another way of writing text?

It is a way of writing bytes. For ASCII text the bytes happen to correspond one-to-one with characters, but for UTF-8 text a character can be several bytes, and for binary data there are no characters at all. Decode hex as UTF-8 only when you know the bytes are UTF-8 text.

When should I use an HTML entity?

When a character would otherwise be parsed as markup — ampersand, angle brackets, and quotes inside attributes — or when the source encoding cannot carry the character. Modern UTF-8 pages can contain the character directly; entities are for escaping, not for decorating ordinary text.

Why does a superscript ² not match a normal 2?

Because they are different code points: ² is U+00B2 and 2 is U+0032. They render differently and compare differently. If the value must match ordinary digits, use normal digits with HTML sup markup, or normalise the text before comparison.