Το **UTF-8** (8-bit Unicode Transformation Format) είναι μη-απωλεστικό σχήμα κωδικοποίησης χαρακτήρων μεταβλητού μήκους για το πρότυπο Unicode που δημιουργήθηκε από τους Ken Thompson και Rob Pike. Χρησιμοποιεί ομάδες από byte για να αναπαραστήσει τα κωδικά σημεία του Unicode. Είναι ιδιαίτερα χρήσιμο για μετάδοση δεδομένων σε 8bit συστήματα ηλεκτρονικού ταχυδρομείου. 

Συγκεκριμένα χρησιμοποιεί ένα μέχρι τέσσερα byte ανά χαρακτήρα ανάλογα με το σύμβολο και το κωδικό του σημείο. Για παράδειγμα χρειάζεται μόνο ένα byte του UTF-8 για την κωδικοποίηση των 128 ASCII χαρακτήρων στο διάστημα του Unicode U+0000 μέχρι U+007F.

Τέσσερα byte μπορεί να φαίνονται πολλά για έναν χαρακτήρα (κωδικό σημείο), παρ'όλα αυτά αυτό αφορά μόνο κωδικά σημεία εκτός του Βασικού πολυγλωσσικού επιπέδου, τα οποία σπάνια χρησιμοποιούνται. Επίσης το UTF-16 (το κύριο εναλλακτικό σχήμα στο UTF-8) επίσης χρειάζεται τέσσερα byte για αυτά τα κωδικά σημεία. Το πιο είναι αποδοτικότερο το UTF-8 ή το UTF-16, εξαρτάται από το εύρος των κωδικών σημείων που θα χρησιμοποιηθούν. Οι διαφορές των δυο σχημάτων μπορούν όμως να γίνουν αμελητέες με την χρήση παραδοσιακών συστημάτων συμπίεσης όπως DEFLATE. Για μικρά κομμάτια κειμένου όπου οι παραδοσιακοί αλγόριθμοι δεν αποδίδουν καλά και όπου το μέγεθος του αρχείου μετράει μπορεί να χρησιμοποιηθεί και το Πρότυπο Σχήμα Συμπίεσης για Unicode.

Η IETF (Internet Engineering Task Force) απαιτεί όλα τα πρωτόκολλα Διαδικτύου να αναγνωρίζουν και να υποστηρίζουν τουλάχιστον ως σχήμα κωδικοποίησης χαρακτήρων τουλάχιστον το UTF-8.

Περιγραφή
---------

Το UTF-8 έχει γίνει το πρότυπο γνωστό ως RFC 3629 (*UTF-8, μια μορφή μετασχηματισμού του καθολικού συνόλου χαρακτήρων ISO 10646*).

Συνοπτικά, τα bit ενός χαρακτήρα Unicode διαιρούνται σε ομάδες οι οποίες κατόπιν διαιρούνται ανάμεσα στα χαμηλότερης αξίας bit μέσα σε UTF-8 byte.

Ένας χαρακτήρας που το κωδικό του σημείο είναι μικρότερο του U+0080 κωδικοποιείται με ένα μόνο byte που περιέχει το κωδικό σημείο: αυτό το σύνολο χαρακτήρων αντιστοιχεί στους 128 χαρακτήρες του ASCII των 7-bit.

Σε άλλες περιπτώσεις απαιτούνται μέχρι και τέσσερα byte. Το πιο σημαντικό bit αυτών των byte είναι 1, για να αποφευχθεί η σύγχυση με τους ASCII χαρακτήρες των 7-bit, και συγκεκριμένα με τους χαρακτήρες με κωδικά σημεία μικρότερα του U+0020, που παραδοσιακά ονομάζονται χαρακτήρες ελέγχου, όπως η επιστροφή φορέα (carriage return).

|  |  |  |  |
| --- | --- | --- | --- |
| Εύρος κωδικώνδεκαεξαδικό | UTF-16 | UTF-8δυαδικό | Σημειώσεις |
| 000000 - 00007F | 00000000 0xxxxxxx | 0xxxxxxx |  εύρος ισοδυναμίας με το πρότυπο ASCII, το byte αρχίζει με 0 |
| επτά x | επτά x |
| 000080 - 0007FF | 00000xxx xxxxxxxx | 110xxxxx 10xxxxxx | το πρώτο byte αρχίζει με 110 ή 1110, το επόμενο ή επόμενα byte αρχίζουν με 10 |
| τρία x, οκτώ x | πέντε x, έξι x |
| 000800 - 00FFFF | xxxxxxxx xxxxxxxx | 1110xxxx 10xxxxxx 10xxxxxx |
| οκτώ x, οκτώ x | τέσσερα x, έξι x, έξι x |
| 010000 - 10FFFF | 110110xx xxxxxxxx 110111xx xxxxxxxx | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx | το UTF-16 απαιτεί αντιπροσώπους (surrogates), αφαιρείται μια μετατόπιση 0x10000, ώστε η ακολουθία bit να μην είναι ίδια με το UTF-8 |
| δύο x, οκτώ x, δύο x, οκτώ x | τρία x, έξι x, έξι x, έξι x |

Για παράδειγμα ο χαρακτήρας άλεφ (א), που είναι ο χαρακτήρας Unicode με κωδικό σημείο U+05D0, μέσω του σχήματος UTF-8 κωδικοποιείται ως εξής:

* Βρίσκεται στο διάστημα U+0080 - U+07FF. Ο πίνακας δείχνει ότι θα κωδικοποιηθεί χρησιμοποιώντας δύο byte *110*xxxxx *10*xxxxxx.
* Ο δεκαεξαδικός 0x05D0 είναι ισοδύναμος στον δυαδικό 101-1101-0000.
* Τα έντεκα bit τοποθετούνται με την σειρά που έχουν στις θέσεις που σημειώνονται με "x" : 110**10111** 10**010000**.
* Το τελικό αποτέλεσμα είναι δύο byte, που για οικονομία τα εκφράζουμε ως δύο byte στο δεκαεξαδικό 0xD7 0x90. Αυτό είναι το γράμμα άλεφ στο σχήμα UTF-8.

Έτσι οι πρώτοι 128 χαρακτήρες χρειάζονται ένα byte. Οι επόμενοι 1920 χαρακτήρες χρειάζονται δύο byte. Αυτοί περιλαμβάνουν Λατινικούς χαρακτήρες και σύμβολα, Ελληνικούς, Κυριλλικούς, Κοπτικούς, Αρμενικούς, Εβραϊκούς, και Αραβικούς χαρακτήρες. Οι επόμενοι από τους BMP χαρακτήρες χρησιμοποιούν τρία byte και οι υπόλοιποι χαρακτήρες κωδικοποιούνται με τέσσερα byte.

Συνεχίζοντας παρόμοια είναι δυνατό να χειριστούμε πολύ μεγάλους αριθμούς. Αρχικά το πρότυπο επέτρεπε ακολουθίες μέχρι έξι byte καλύπτοντας το διάστημα U+0000 - U+7FFFFFFF (31 bits). Όμως τελικά το UTF-8 περιορίστηκε από το RFC 3629 να χρησιμοποιεί μόνο το διάστημα που καλύπτει τυπικά το Unicode, από U+0000 ως U+10FFFF, το Νοέμβριο του 2003. Πριν συμβεί αυτό μόνο τα byte 0xFE και 0xFF δεν εμφανίζονταν σε UTF-8 κωδικοποιημένο κείμενο. Μετά την εισαγωγή αυτού του ορίου ο αριθμός των αχρησιμοποίητων byte σε UTF-8 κείμενο αυξήθηκε σε 13 byte: 0xC0, 0xC1, και 0xF5 μέχρι 0xFF.

Τροποποιημένο UTF-8
-------------------

Η Γλώσσα προγραμματισμού Java, που χρησιμοποιεί UTF-16 για την εσωτερική αναπαράσταση κειμένου υποστηρίζει μια μη-τυποποιημένη τροποποίηση του UTF-8 για σειριοποίηση συμβολοσειρών. Αυτή η κωδικοποίηση λέγεται modified UTF-8.

Σκεπτικό πίσω από UTF-8
-----------------------

Ως συνέπεια της λειτουργίας του UTF-8, ισχύουν οι ακόλουθες ιδιότητες για ακολουθίες πολλών byte:

* Το πιο σημαντικό bit ενός χαρακτήρα ενός byte είναι πάντα `0`.
* Τα πιο σημαντικά bit του πρώτου byte μιας ακολουθίας πολλών byte καθορίζει το μήκος της ακολουθίας. Αυτά τα πιο σημαντικά bit είναι τα `110` για ακολουθίες δύο byte, τα `1110` για ακολουθίες τριών byte κτλ.
* Τα ακόλουθα byte μιας ακολουθίας πολλών byte έχουν `10` ως τα δύο πιο σημαντικά bits.

Το UTF-8 σχεδιάστηκε με αυτές τις ιδιότητες προκειμένου να εγγυηθεί ότι δεν θα είναι δυνατό μια ακολουθία byte ενός χαρακτήρα να περιέχεται μέσα σε μια μεγαλύτερη ακολουθία byte ενός άλλου χαρακτήρα. Αυτό εξασφαλίζει ότι μπορούμε να εφαρμόσουμε ταίριασμα υπό-συμβολοσειρών με βάση τα byte για αναζήτηση λέξεων και φράσεων μέσα σε κείμενο.

Μερικά παλιότερα σχήματα κωδικοποίησης 8-bit (όπως το Shift-JIS) δεν είχαν αυτήν την ιδιότητα κάνοντας τους αλγόριθμους ταιριάσματος συμβολοσειρών πολύπλοκους. Παρόλο που αυτή η ιδιότητα προσθέτει πλεονασμό σε UTF-8-κωδικοποιημένο κείμενο 
τα πλεονεκτήματα ξεπερνούν τα μειονεκτήματα και, εξάλλου, η συμπίεση δεδομένων δεν είναι στόχος του Unicode και πρέπει να εξεταστεί ξεχωριστά. Ακόμα αυτές οι ιδιότητες επιτρέπουν επανασυγχρονισμό στον επόμενο χαρακτήρα ενός ρεύματος κειμένου που μεταδίδεται από ένα σημείο σε κάποιο άλλο σε περίπτωση που χαθούν κάποια byte λόγω βλάβης. 

Επίσης λόγω του σχεδιασμού των ακολουθιών byte, αν μια ακολουθία που υποθέτουμε ότι αναπαριστά κείμενο επαληθευτεί σαν UTF-8 τότε με μεγάλη σιγουριά μπορούμε να υποθέσουμε ότι είναι UTF-8. Η οικογένεια προτύπων ISO-8859 χρησιμοποιεί 100xxxxx για εξαιρετικά σπάνιους κωδικούς ελέγχου. Και κάποιες άλλες παραδοσιακές κωδικοποιήσεις χρησιμοποιούν byte σε αυτό το διάστημα αλλά μόνο για σπάνιους χαρακτήρες.

Μπορούν να χρησιμοποιηθούν σχήματα bit προκειμένου να αναγνωριστούν UTF-8 χαρακτήρες. Αν το πρώτο byte στο δεκαεξαδικό αρχίζει με 0-7 είναι χαρακτήρας ASCII. Αν αρχίζει με C ή D, είναι χαρακτήρας 11 bit (εκφρασμένος με δυο byte). Αν αρχίζει με E είναι 16 bit (εκφρασμένος σε 3 byte) και αν αρχίζει με F, είναι 21 bit εκφρασμένος σε 4 byte).
8 μέχρι B δεν μπορούν να είναι αρχικά ψηφία, αλλά όλα τα *ακόλουθα* byte πρέπει να αρχίζουν με ψηφίο ανάμεσα στο 8 και το B. Έτσι με μια ματιά μπορείς να πεις ότι ο "0xA9" δεν είναι έγκυρος UTF-8 χαρακτήρας, αλλά ότι οι "0x54", "0xE3 0xB4 ή 0xB1" *είναι*  έγκυροι UTF-8 χαρακτήρες.

Μακρές φόρμες, μη-έγκυρη είσοδος,και θέματα ασφάλειας
-----------------------------------------------------

Η ακριβή απόκριση ενός αποκωδικοποιητή σε μη-έγκυρη είσοδο είναι ακαθόριστη σε εκτεταμένο βαθμό. Υπάρχουν πολλοί τρόποι με τους οποίους ένας αποκωδικοποιητής μπορεί να αποκριθεί σε μη-έγκυρη είσοδο:

1. Εισαγωγή χαρακτήρα αντικατάστασης (π.χ. '?', '�')
2. Να προσπεράσει τον χαρακτήρα
3. Να μεταφράσει τον χαρακτήρα σαν να ήταν από άλλο σύνολο χαρακτήρων (συχνά Latin-1)
4. Να μεταφράσει όλο το κείμενο σαν να ήταν από άλλο σύνολο χαρακτήρων

(συχνά Latin-1 ή το τοπικό σύνολο χαρακτήρων), κάτι που συμβαίνει σε εφαρμογές όπως IRC όπου το UTF-8 δεν είναι καθολικά αποδεκτό και δεν υπάρχει ενσωματωμένος στο πρόγραμμα τρόπος για να καθοριστεί το σύνολο χαρακτήρων.

1. Να αδιαφορήσει και να αποκωδικοποιήσει σαν ο χαρακτήρας να ήταν κάποιος παραπλήσιος του UTF-8
2. Να αναφέρει λάθος

Δείτε επίσης
------------

* Απλό κείμενο
* ASCII
* ISO 8859
* GB18030
* Universal Character Set
* Byte Order Mark
* Unicode and HTML
* Character encodings in HTML
* Unicode and e-mail
* Complex script

Εξωτερικοί σύνδεσμοι
--------------------

* Ο Rob Pike διηγείται την ιστορία της δημιουργίας του UTF-8
* Η αρχική UTF-8 εργασία
* RFC 3629, το UTF-8 πρότυπο
* RFC 2277, IETF πολιτικές σε σύνολα χαρακτήρων και γλώσσες
* UTF-8 και Unicode FAQ
* UTF-8
* UTF-8 δοκιμαστική σελίδα
* ακόμα μια UTF-8 δοκιμαστική σελίδα Αρχειοθετήθηκε 2017-11-30 στο Wayback Machine.
* UTF-8 και Debian και Linux UTF-8 How-To.
* SIL's freeware γραμματοσειρές, επεξεργαστές κειμένου και τεκμηρίωση