# UTF-8

UTF-8 (8-bit Unicode Transformation Format) is een manier om Unicode/ISO 10646-tekens op te slaan als een stroom van bytes, een zogenaamde tekencodering. Alternatieven zijn UTF-16 en UTF-32.
UTF-8 is een tekencodering met variabele lengte: niet elk teken gebruikt evenveel bytes. Afhankelijk van het teken worden 1 tot 4 bytes gebruikt. Voor de 128 ASCII-tekens is slechts één byte nodig, waarvan de numerieke waarde gelijk is aan de ASCII-code. Voor alle andere tekens zijn twee of meer bytes nodig.
Vóór de komst van Unicode gebruikten veel landen een uitbreiding op de ASCII-tekenset met taalspecifieke tekens in de posities 128-255.

## Beschrijving

UTF-8 is gestandaardiseerd als RFC 3629 (UTF-8, a transformation format of ISO 10646).
Samenvattend worden de Unicodetekens in groepen bits ingedeeld die worden verdeeld over de lage bits van de UTF-8-bytes.
De tekens U+0000..U+007F, de ASCII-tekens, kunnen direct worden gecodeerd in een byte met de hoogste bit 0. Voor alle andere tekens zijn 2 tot 4 bytes nodig. Alle bytes voor zulke tekens hebben de hoogste bit 1, zodat verwarring met de ASCII-tekens wordt voorkomen.
In dat laatste geval zijn bij de eerste byte de hoogste twee bits gelijk aan '11' en bij de volgende byte(s) '10'. Hierdoor kan altijd de eerste byte van een in UTF-8 gecodeerd teken worden herkend. De positie van de hoogste '0' in de eerste byte geeft aan uit hoeveel bytes de code is samengesteld.
| Codegebied hexadecimaal | UTF-32 binair | UTF-16 binair | UTF-8 binair | Opmerking over de UTF-8-code |
| U+0000..U+007F | 00000000 00000000 00000000 0aaaaaaa | 00000000 0aaaaaaa | 0aaaaaaa | ASCII-equivalenten; byte begint met nulbit |
| U+0080..U+07FF | 00000000 00000000 00000bbb aaaaaaaa | 00000bbb aaaaaaaa | 110bbbaa 10aaaaaa | eerste byte begint met 110, tweede met 10 |
| U+0800..U+D7FF en U+E000..U+FFFF | 00000000 00000000 bbbbbbbb aaaaaaaa | bbbbbbbb aaaaaaaa | 1110bbbb 10bbbbaa 10aaaaaa | eerste byte begint met 1110, volgende met 10 |
| U+010000..U+10FFFF (1.048.576 supplementaire codepunten) | 00000000 000ccccc bbbbbbbb aaaaaaaa | 110110dd ddbbbbbb 110111bb aaaaaaaa | 11110ccc 10ccbbbb 10bbbbaa 10aaaaaa | eerste byte begint met 11110, volgende met 10, dddd = ccccc − 1 |
De codes U+D800..U+DFFF zijn uitgezonderd van het codegebied U+0800..U+FFFF, om in UTF-16 codes van twee bytes te kunnen onderscheiden van de eerste of laatste twee bytes van codes van vier bytes (de eerste van de twee bytes is niet van de vorm 110110dd of 110111bb). Ze worden wel gebruikt om zogenaamde surrogaatparen van vier bytes samen te stellen, maar die zijn niet in Unicode gedefinieerd.
Zoals blijkt uit de niet-overlappende codegebieden in de linker kolom mag bijvoorbeeld U+007F (binair 01111111) in UTF-8 alleen als 7F gecodeerd worden en niet als C1 BF (wat het volgens het schema 110bbbaa 10aaaaaa zou zijn). Het komt erop neer dat alleen de kortste vorm is toegestaan.

## Toegestane karakters

Volgens de oorspronkelijke specificatie kon een UTF-8-code uit maximaal zes bytes bestaan. Om compatibiliteit met UTF-16 te garanderen werd dit verkort tot maximaal vier bytes en werd U+10FFFF het hoogste toegestane Unicodeteken.
Een omzetter voor UTF-8-code dient tekst met ongeldige codes te verwerpen vanwege beveiligingsrisico's.

## Voordelen

* In ASCII gecodeerde tekst is ongewijzigd geldig als UTF-8-tekst.
* Doordat de letters uit het Latijnse alfabet slechts één byte in beslag nemen, is UTF-8 voor westerse talen compacter dan het eenvoudigere UTF-16. Textbestanden met opmaaktaal, zoals HTML of XML (in het bijzonder bestanden in het docx- of odf-formaat), bevatten daarnaast veel codewoorden in ASCII, ook voor bestanden in niet-westerse talen.
* UTF-8 is onafhankelijk van de endianness van de computer (in tegenstelling tot UTF-16) en daardoor geschikter als uitwisselingsformaat.
* Het is veel eenvoudiger Unixsystemen compatibel te maken met UTF-8 dan met UTF-16, bijvoorbeeld doordat programma-API's voor de programmeertaal C ongewijzigd kunnen blijven (zowel in ASCII als in UTF-8 kan een tekenreeks worden behandeld als een nul-getermineerde char*; een UTF-16-tekenreeks bevat gewoonlijk veel nulbytes en wordt meestal behandeld als een short*).
* UTF-8-tekenreeksen kunnen worden gesorteerd alsof het bytereeksen zijn.
* Woordbreekroutines voor ASCII werken met UTF-8 correct zonder wijziging.
* Bestandsnaamroutines voor ASCII werken met UTF-8 correct (alle speciale tekens in bestandsnamen en paden zijn ASCII-tekens)
* Doordat de eerste byte aangeeft in hoeveel bytes een teken gecodeerd is, is de variabele lengte van de tekens in UTF-8 gemakkelijk te decoderen. Doordat bovendien vervolgbytes als zodanig onderscheidbaar zijn, kan een teken niet als deelreeks van een ander teken gecodeerd zijn, zodat zoekacties geen onjuiste resultaten kunnen opleveren, ook al wordt niet vanaf het begin van de tekst gezocht.

## Nadelen

* De variabele lengte maakt het in veel programmeertalen lastiger direct met tekenreeksen te werken omdat het n$^e$ teken niet altijd meer correspondeert met de n$^e$ byte. Dit kan worden opgelost door hiervoor de juiste bibliotheken te gebruiken. Bijvoorbeeld in Flash is het commando System.useCodepage=true nodig om UTF-8 te kunnen gebruiken. Dit probleem is echter ook van toepassing bij codering in UTF-16, dat eveneens variabele breedte heeft.
* Veel Oost-Aziatische tekens gebruiken drie bytes in UTF-8, terwijl ze slechts twee bytes zouden gebruiken in UTF-16. Hierdoor worden tekstbestanden in deze talen groter dan in UTF-16. Belangrijke documentformaten zoals html, docx of odt bestaan echter voor een groot deel uit XML (achtige) opmaak in ASCII die in UTF-8 juist maar één byte nodig heeft. Ook verdwijnen verschillen in codering na compressie. In de praktijk is ook voor documenten in Oost-Aziatische talen het verschil in grootte tussen UTF-16 en UTF-8 daarom meestal minimaal.
* Windows en de programmeertalen Java en C# zijn ingericht op het gebruik van tekenreeksen in UTF-16 in plaats van UTF-8.

## Gebruik

UTF-8 werd in 1993 geïntroduceerd. Rond het jaar 2000 stapten de op Linux gebaseerde distributies over naar UTF-8 als standaard voor alle tekstbestanden (inclusief scriptbestanden). Aan de bestanden zelf is niet te zien of deze in UTF-8 gecodeerd zijn. Dat blijkt pas bij het bekijken van de tekst.
Microsoft was eerder al op UTF-16 overgegaan, maar heeft ook UTF-8 toegevoegd. Indien in Microsoft Windows platte tekst in UTF-8 wordt opgeslagen, voegen Microsoftprogramma's de drie bytes 0xEF, 0xBB en 0xBF, de UTF-8-code voor U+FEFF, aan het begin van het bestand toe, het "Byte Order Mark", of kortweg "BOM", dat echter niet altijd door andere programma's goed herkend wordt.
Webpagina's kunnen ook UTF-8 gebruiken. In de broncode van de webpagina's wordt dan aangegeven dat het om UTF-8-code gaat. De meeste websitemakers geven de voorkeur aan UTF-8, omdat dit bij andere talen minder onduidelijkheden geeft dan de ASCII- of ANSI-tekenset. Wikipedia gebruikt bijvoorbeeld UTF-8 voor alle tekst en ook in e-mail wordt steeds vaker UTF-8 gebruikt.

## Externe link

* UTF-8-tabellen - UTF-8-tekens in een aantal variëteiten getoond (gebruik het uitklapmenu op de derde regel om een blok te selecteren)
* ↑ RFC 3629
* ↑ OWASP Wiki - Encoded Injection
* ↑ Usage of character encodings for websites