blog

How to convert text to Unicode code points

koboshi · Co-founder

Try it yourself

Everything in this article runs live in the converter. Paste your own text and watch every notation update at once.

Open the Unicode converter

Paste café 😀 into the main input of the Unicode converter and the Hex code points panel answers with six numbers:

hex code points panel
0063 0061 0066 00E9 0020 1F600

That is the whole job of a text to Unicode conversion: replace each character with the code point the standard assigns to it. Reading left to right, 0063 is LATIN SMALL LETTER C, 0061 is A, 0066 is F, 00E9 is é (LATIN SMALL LETTER E WITH ACUTE), 0020 is SPACE, and 1F600 is 😀 (GRINNING FACE). The emoji is a single code point even though it does not fit in four hex digits, and even though JavaScript stores it as two UTF-16 code units. More on that below.

Four notations for the same numbers

A code point is an integer between 0 and 0x10FFFF. The integer behind é is 233, and everything else is notation. Different contexts have settled on different conventions, so the converter offers all four.

U+ notation

The Unicode Standard's own convention: U+ followed by at least four uppercase hex digits, so é is written U+00E9 and 😀 is U+1F600. Specifications, Unicode data file documentation, and careful bug reports use it, because it cannot be confused with a number or an escape sequence. The Unicode U+ notation panel produces it. With Keep ASCII checked (the default on this panel), ASCII letters stay as text and only the rest becomes codes: cafU+00E9 U+1F600. Uncheck it and every character becomes a code, run together with no separators: U+0063U+0061U+0066U+00E9U+0020U+1F600. That is what the Separate button is for: it inserts a space before each U+ and gives you U+0063 U+0061 U+0066 U+00E9 U+0020 U+1F600. Separate only reformats the box. If you Convert from it afterward, those extra spaces travel into the result, so the round trip is no longer exact.

0x notation

C, C++, Java, JavaScript and most debuggers write hexadecimal numbers with a 0x prefix: 0xE9 is just the number 233. The 0x notation panel mirrors that style. The default output for the opening string is caf0xE9 0x1F600; with Keep ASCII off it is 0x630x610x660xE90x200x1F600, and Separate spaces it out again. Reach for this form when you are pasting values into source code or comparing against what a debugger prints.

Bare hex

Space-separated hex with no prefix is the data exchange form. Unicode's own machine-readable files use it: the first field of every line in UnicodeData.txt is a bare hex code point. This is the Hex code points panel from the opening example, and it is the easiest format to feed into scripts and command-line tools.

Decimal

Some markup and APIs count in base ten. HTML numeric character references come in both bases: é is é in decimal or é in hex. JavaScript's String.fromCodePoint takes the number itself, where fromCodePoint(233) and fromCodePoint(0xE9) are the same call. The Decimal code points panel renders the opening string as 99 97 102 233 32 128512.

Keep ASCII, padding, and the "cafe" trap

Two options shape the Hex code points panel. Keep ASCII, off by default here, leaves ASCII characters as text mixed into the numbers, so café 😀 becomes caf00E9 1F600. Readable, but look closely: caf and 00E9 have fused into caf00E9, which no longer round-trips as the original text. Pad to digits controls leading zeros: 4 (the default) matches the minimum width of U+ notation, 2 is compact, 8 mimics a 32-bit view and turns the emoji into 0001F600. Padding never truncates: at pad 4 the emoji stays 1F600.

The panel also works in reverse. Paste 0063 0061 0066 00E9 0020 1F600 into it, hit Convert, and the Characters panel shows café 😀. The space is the delimiter, and that has a sharp edge. Hex digits include the letters a through f, so the word "cafe" with no spaces is one valid hex number: 0xCAFE, decimal 51,966. Convert it and you get a single Hangul syllable, 쫾 (U+CAFE, HANGUL SYLLABLE JJWAELM), not the start of a coffee order. The same rule bites in the main input: when Treat bare numbers as is set to hex code points, a word like cafe counts as a number there too. A related trap: in W3C202C the digits read as one number, 3C202C, which sits beyond the top of the codespace, and the tool answers hex2Char error: Code point out of range: 3C202C. Keep numbers spaced, and spaced away from letters.

Code points are not code units

One more precision. The 😀 in the example is one code point, U+1F600, but the UTF-16 code units panel shows D83D DE00: two 16-bit code units, a lead surrogate followed by a trail surrogate (also called high and low surrogate). Code points are the numbers Unicode assigns. Code units are what an encoding form uses to store them. That distinction is why JavaScript has two methods that look interchangeable and are not.

The same conversion in JavaScript

javascript
const text = "café 😀"

// The spread iterates code points, so the emoji stays one element.
const codes = [...text].map(
  (ch) => "U+" + ch.codePointAt(0).toString(16).toUpperCase().padStart(4, "0")
)
// [ "U+0063", "U+0061", "U+0066", "U+00E9", "U+0020", "U+1F600" ]

text.codePointAt(5)   // 128512, the code point of 😀
text.charCodeAt(5)    // 55357 (0xD83D), a UTF-16 code unit, not a code point

String.fromCodePoint(0x63, 0x61, 0x66, 0xE9, 0x20, 0x1F600)
// "café 😀"

Three rules keep this snippet safe. Iterate with the spread operator or for...of, never a numeric index, so supplementary characters stay whole. Use codePointAt and String.fromCodePoint for code points; charCodeAt and String.fromCharCode speak UTF-16 code units and will split anything above U+FFFF. And convert bases explicitly: toString(16) and parseInt(x, 16) do not care which notation the digits originally came from.

Which notation, when

  • Writing or reading a spec, a Unicode chart, or a precise bug report: U+ notation with at least four digits.
  • Working in C-family source code or a debugger: 0x.
  • Handing data to scripts or command-line tools: space-separated bare hex, padded to 4.
  • Feeding HTML or an API that counts in base ten: decimal.
  • Pasting numbers back into the converter: whatever the notation, keep spaces between numbers and keep numbers away from stray letters.

If the idea of a code point still feels abstract, start with What is Unicode?. The lead and trail surrogate story continues in What is UTF-16?.

Try it yourself

Everything in this article runs live in the converter. Paste your own text and watch every notation update at once.

Open the Unicode converter