Anyone who has opened an old Word file from a Vietnamese school or office has seen it: "Vieät Nam", "ViÖt Nam" or "Việt Nam" where "Việt Nam" should be. The text is not lost. It was stored correctly in one encoding and is being read in another, and each kind of garbage has a fingerprint that tells you which mistake happened. This article explains the encodings Vietnamese has gone through, shows what each one looks like when it goes wrong, and how to get the text back. The conversions below were all produced with the Vietnamese text tools.
Why Vietnamese is hard for computers
The Vietnamese alphabet has 29 letters, 12 of them vowels, and five tone marks that can sit on any vowel. Counting every combination of vowel, vowel mark and tone, there are 67 lower-case letters with marks plus their capitals: 134 characters beyond plain A–Z. A letter like "ệ" carries two marks at once, a circumflex and a dot below.
The early computer world was built around ASCII, which has 128 codes, and its 8-bit extensions, which have 256. Western European languages fit their few accented letters into the upper 128 codes. Vietnamese does not fit: 134 extra letters is more than the 128 free codes, before you even count punctuation. Every solution before Unicode was a compromise.
The three old answers
VNI (fonts such as VNI-Times) stores most letters as two bytes: the base letter followed by a byte for its marks. "ệ" is "e" followed by a byte that the font draws as circumflex-plus-dot. A handful of letters get a single byte: "ơ", "ư", "đ" and the i's.
TCVN3, also called ABC (fonts such as .VnTime and .VnArial), was the national standard TCVN 5712:1993. It gives every lower-case letter one byte, but only has room for seven capitals: Ă, Â, Ê, Ô, Ơ, Ư and Đ. A capital with a tone, like the "Ệ" in "VIỆT NAM", simply has no code. Typists wrote headings in lower case and switched to a capital font (.VnTimeH), which draws the lower-case codes as capitals.
VIQR (RFC 1456) avoided special bytes altogether by writing marks as ASCII punctuation after the vowel: "Vie^.t Nam", "ddu+o+`ng". It was used in email and newsgroups in the 1990s, where 8-bit text often got mangled.
All three worked as long as everybody had the same fonts installed. The bytes on disk only meant Vietnamese letters if the font said so.
What each kind of garbage looks like
When the matching font is missing, Windows shows those bytes as Western European letters (the Windows-1252 code page). Each encoding then produces a recognisable pattern:
| Text | VNI shown in a normal font | TCVN3 shown in a normal font |
|---|---|---|
| Việt Nam | Vieät Nam | ViÖt Nam |
| Tiếng Việt | Tieáng Vieät | TiÕng ViÖt |
| Hà Nội | Haø Noäi | Hµ Néi |
| Đường đời | Ñöôøng ñôøi | §êng ®êi |
Fingerprints: VNI keeps the base vowels and follows them with ä, á, ø, õ, ï; its "đ" turns into "ñ" and "ư" into "ö". TCVN3 replaces the whole letter with a single odd character such as Ö, Õ, µ, ® or §. TCVN3's "ư" is the byte 0xAD, which Windows-1252 defines as a soft hyphen, an invisible character, so "người" can show up as "ngêi" with the "ư" apparently missing. It is often still there, invisible; but if the text has passed through a program that strips soft hyphens, it is gone for good.
The modern variant is different. "Việt Nam" is not a legacy font at all: it is correct UTF-8 Unicode read as Windows-1252. "ệ" is three bytes in UTF-8 (E1 BB 87), and each byte shows up as its own Western character: á, », ‡. You will see this in CSV files opened in Excel, in old databases and in emails with a missing charset header.
How to fix each case
- VNI or TCVN3 garbage: paste it into the encodings tab of the Vietnamese text tools and leave the source on automatic detection. The tool counts the fingerprints above to decide which encoding it is, converts to Unicode and tells you whether the detection was clear or a guess. A paragraph is plenty; a single word can be ambiguous, so choose the encoding yourself if the result looks half right.
- TCVN3 headings in capitals: tick the capital-font option, because the text itself only contains lower-case codes.
- UTF-8 read as Windows-1252 ("Việt"): do not copy the garbage around, fix the way the file is opened. In Excel, use Data → From Text/CSV and choose 65001: Unicode (UTF-8) as the file origin; in a text editor, reopen with UTF-8. When you write CSV files for Excel, save them as UTF-8 with a byte-order mark.
- A whole old .doc file in VNI or TCVN3: a desktop converter such as the one built into UniKey (it works on the clipboard and on RTF content, keeping formatting) is faster than pasting page by page; this page is for pasted text.
Same letters, different bytes: NFC and NFD
Even inside Unicode there are two ways to store "ệ". NFC uses one code point (U+1EC7). NFD uses "e" followed by two combining marks, the circumflex and the dot below. "Việt" is 4 code points in NFC and 6 in NFD. On screen they look identical, but a search for one does not find the other, and a database may treat them as different names. macOS file names and some PDF text are often NFD. The tool accepts both and always returns NFC, and tells you when it had to join decomposed letters.
Common mistakes
- Retyping instead of converting. A converter fixes 20 pages in a second, with no typos.
- Converting twice. Running a legacy-to-Unicode conversion on text that is already Unicode can scramble correct letters. Look at the text first; if it already reads correctly, leave it alone.
- Guessing from one word. "Noäi" could be VNI; "Néi" could be TCVN3 or a French typo. Use a longer sample.
- Saving new text in a legacy encoding. Only do it for a system that demands it, such as an old template. Everything else should be Unicode (UTF-8).
- Mixing tone styles. "hòa" and "hoà" are both correct but are different strings. Converted text keeps whatever the original typist used; normalise it if you need consistent search.
Removing accents and making slugs
Sometimes you want the marks gone on purpose: for a URL, a file name or an ASCII-only system. Removing them is more than deleting combining characters, because "đ" is a separate letter, not "d" plus a mark: "Đường đời" must become "Duong doi". A URL slug goes further and lower-cases and joins words: "duong-doi-dau-phai-duong-thang". Both are one click in the Vietnamese text tools; for word counts and other languages, use the text toolkit.