Az UTF-8 (az univerzális karakterkészlet- átalakítási formátum rövidítése - 8 bit ) egy számítógépes karakterkódolás, amelyet az eredetileg az ISO által a szabványban kifejlesztett "univerzális kódolt karakterkészlet" karakterkészletének kódolására terveztek . Nemzetközi ISO / IEC 10646 , immár teljes mértékben kompatibilis az Unicode szabvánnyal , miközben kompatibilis marad az ASCII szabvánnyal, amely az angol nyelvre korlátozódik, de évtizedek óta széles körben használják.
Az UTF-8-at a weboldalak 82,2% -a használja 2014. december, 2016-ban 87,6%, 2017-ben 90,5%, 2017-ben 93,1% 2019. február és közel 95,2% -ban 2020 október. Jellegéből adódóan az UTF-8-ot egyre inkább használják az interneten és azokban a rendszerekben, amelyekben információcserére van szükség. Ez a GNU , a Linux és a kompatibilis rendszerek legelterjedtebb kódolása a szövegek és fordításaik lehető legegyszerűbb kezelésére a világ összes írórendszerében és ábécéjében.
UTF-8 egy „transzformáció formátum” eredetileg a munkából a ISO / IEC 10646 szabvány , azaz UTF-8 meghatároz egy kódolási bármilyen skalár kódot pont ( absztrakt karakter vagy "nem-karakter„) a Universal Character Set ( UCS ) Könyvtár. Ez a könyvtár most már közös az ISO / IEC 10646 szabványban (az 1. változat óta) és az Unicode szabványban (az 1.1-es verzió óta).
Az UTF-8-ot hivatalosan meghatározza az ISO / IEC 10646 szabvány , annak elfogadása óta, egy 1996-ban közzétett módosításban. Ezt az Unicode szabvány is leírta, és a 2000-ben megjelent 3.0 verzió óta ennek a szabványnak része. 1996-ban megjelent a RFC 2044 (" UTF-8, az ISO 10646 átalakítási formátuma ") az UTF-8 hozzáférhető specifikációjának biztosítása és szabványosításának megkezdése érdekében az Internet Engineering Task Force (IETF) keretein belül . Ezt az RFC-t 1998-ban ( RFC 2279), majd végül 2003-ban ( RFC 3629) felülvizsgálták , utóbbi verzióval az UTF-8 az Internet egyik szabványává vált (STD 63).
Technikailag ez magában foglalja az Unicode karakterek kódolását egy- egy byte egy- négy kódpont szekvenciák formájában . Az Unicode szabvány meghatározza többek között a karakterek halmazát (vagy könyvtárát). Minden karaktert ebben a halmazban egy teljes index azonosít, amelyet „ kódpontnak ” is neveznek . Például a karakter „€” ( euró ) a 8365 th jellegét Unicode könyvtár, az index, vagy kódot pont, tehát 8364 (0x20AC) (kezdjük számlálás 0).
Az Unicode könyvtár több mint egymillió karaktert tartalmazhat, ami túl nagy ahhoz, hogy egyetlen bájtként kódolható legyen (0 és 255 közötti értékekre korlátozva). Az Unicode szabvány ezért szabványosított módszereket határoz meg ennek az indexnek a bájtsorozat formájában történő kódolására és tárolására: az UTF-8, az UTF-16 , az UTF-32 és ezek különféle változatai mellett.
Az UTF-8 fő jellemzője, hogy visszafelé kompatibilis az ASCII standarddal, vagyis bármelyik ASCII karaktert az UTF-8 kódolja egyetlen bájt formájában, azonos az ASCII kóddal. Például az „A” (nagy A betű) ASCII kódja 65 (0x41), és az UTF-8 kódolja a 65 bájt. Minden olyan karakter, amelynek kódpontja nagyobb, mint 127 (0x7F) (nem ASCII karakter), 4 bájt . Az „€” (euro) karaktert például 3 bájt kódolja: 226, 130 és 172 (0xE2, 0x82 és 0xAC).
A szám (skalár érték) az egyes kódok pont a Universal Character Set (UCS) által adott szabvány ISO / IEC 10646 , amely kijelöli a kódpontot minden karakter érvényes, és lehetővé teszi ezek kódoló hozzárendelésével skalár érték megegyezik a kód pont ; ezt a szabványt az Unicode szabvány tartalmazza (amely ugyanazt a könyvtárat használja az 1.1-es verzió óta).
Az U + 0000-tól az U + D7FF-ig és az U + E000-től az U + 10FFFF-ig minden " kódpont " reprezentálható az UTF-8-ban - még azok is, amelyek a "nem karakterekhez" ( nem karakterekhez ) vannak hozzárendelve, és mindazok, amelyek még nincsenek hozzárendelve - és csak azokat. Az egyetlen kódpont, amely az UCS térben érvényes, és amelyet nem szabad ábrázolni az UTF-8-ban, a " fél-kódpontokhoz " ( angolul helyettesítők ) vannak hozzárendelve , mivel azok valamilyen módon nem ábrázolhatók. Bijective az UTF-16 kódolásban és nem karakter önmagukban vagy: ellentétben más kódpontokat félig kódok ezért azok nem egy meghatározott „ skalár érték ”.
A 0 és 127 közötti skaláris értékű pontkódot (U + 0000 kódpontok U + 007F, az ASCII 7 bitjén kódolt készlet karaktereihez rendelik) egy bájtra kódolják , amelynek a legjelentősebb bitje nulla.
A többi, 127-nél nagyobb skaláris értékű kódot (karakterekhez rendelt vagy nem) (kivéve azokat, amelyekhez "félkódok" vannak hozzárendelve, amelyek nem önmagukban karakterek) több bájtra kódolják, mindegyiknek megvan a sajátja. legjelentősebb bit: a kódolt szekvencia első bájtjának legjelentősebb bitjei 1 hosszúságú szekvenciát alkotnak, amely megegyezik a teljes szekvenciához használt bájtok (legalább 2) teljes számával, majd 0-val és a szükséges következő bájtokkal két legjelentősebb bitjük 10-re áll.
Kódolt karakterek | UTF-8 bináris ábrázolás | Az első érvényes bájt (hexadecimális) | Jelentése |
---|---|---|---|
U + 0000 - U + 007F | 0 xxxxxxx | 00-tól 7F-ig | 1 bájt, 7 bitet kódolva |
U + 0080 - U + 07FF | 11 0 xxxxx 10 xxxxxx | C2-DF | 2 bájt, 11 bitet kódolva |
U + 0800 - U + FFFF | 111 0 xxxx 10 xxxxxx 10 xxxxxx | E0-tól EF-ig | 3 bájt, 16 bitet kódolva |
U + 10000 - U + 10FFFF | 1111 0 xxx 10 xxxxxx 10 xxxxxx 10 xxxxxx | F0 – F4 | 4 bájt, 21 bitet kódolva |
Ezt az elvet nyolc bájtra lehetne kiterjeszteni egyetlen kódpont esetében (legfeljebb 42 bites kódpontok képviseletére), de az UTF-8 jelenlegi szabványosított változata négyre szabja a határt.
A kódolás tiltja képviseletét kódpontokat fenntartott fél kódok (amelyek nem rendelkeznek meghatározott skalár érték megőrzése érdekében kompatibilitás UTF-16 , ami nem teszi lehetővé számukra, hogy képviselteti magát sem). Engedélyezi azonban a nem karakterekhez rendelt kódpontok ábrázolását (annak ellenére, hogy a megfelelő szövegben ezek jelenléte tilos).
típus | karakter |
Kódpont (hexadecimális) |
Skaláris érték | UTF-8 kódolás | ||
---|---|---|---|---|---|---|
decimális | bináris | bináris | hexadecimális | |||
Ellenőrzés | [NEM] | U + 0000 | 0 | 0 | 0 0000000 | 00 |
[MINKET] | U + 001F | 31 | 1111 | 0 0011111 | 1F | |
Szöveg | [SP] | U + 0020 | 32 | 100000 | 0 0100000 | 20 |
NÁL NÉL | U + 0041 | 65 | 100 0001 | 0 100 0001 | 41 | |
~ | U + 007E | 126. | 111 1110 | 0 1111110 | 7E | |
Ellenőrzés | [A] | U + 007F | 127. | 111 1111 | 0 1111111 | 7F |
[PÁRNA] | U + 0080 | 128 | 000 1000 0000 | 110 000 10 10 000 000 | C2 80 | |
[APC] | U + 009F | 159 | 000 1001 1111 | 110 000 10 10 011 111 | C2 9F | |
Szöveg | [NBSP] | U + 00A0 | 160 | 000 1010 0000 | 110 000 10 10 100 000 | C2 A0 |
é | U + 00E9 | 233 | 000 1110 1001 | 110 000 11 10 101 001 | C3 A9 | |
߿ | U + 07FF | 2047 | 111 1111 1111 | 110 111 11 10 111 111 | DF BF | |
ࠀ | U + 0800 | 2048 | 1000 0000 0000 | 1110 0000 10 1000 00 10 000000 | E0 A0 80 | |
€ | U + 20AC | 8 364 | 100000 10101100 | 1110 0010 10 0000 10 10 101100 | E2 82 AC | |
| U + D7FF | 55,295 | 1101 0111 1111 1111 | 1110 1101 10 0111 11 10 111111 | ED 9F BF | |
Fél codet | U + D800 | (semmi) | (kódolás tilos) | |||
U + DFFF | ||||||
Magán felhasználás | [] | U + E000 | 57,344 | 1110 0000 0000 0000 | 1110 1110 10 0000 00 10 0000000 | EE 80 80 |
[] | U + F8FF | 63,743 | 1111 1000 1111 1111 | 1110 1111 10 1000 11 10 111111 | EF A3 BF | |
Szöveg | U + F900 | 63 744 | 1111 1001 0000 0000 | 1110 1111 10 1001 00 10 000 000 | EF A4 80 | |
﷏ | U + FDCF | 64 975 | 1111 1101 1100 1111 | 1110 1111 10 1101 11 10 001111 | EF B7 8F | |
Nem karakterek | U + FDD0 | 64 976 | 1111 1101 1101 0000 | 1110 1111 10 1101 11 10 010000 | EF B7 90 | |
U + FDEF | 65,007 | 1111 1101 1110 1111 | 1110 1111 10 1101 11 10 101111 | EF B7 AF | ||
Szöveg | ﷰ | U + FDF0 | 65,008 | 1111 1101 1111 0000 | 1110 1111 10 1101 11 10 110000 | EF B7 B0 |
U + FFFD | 65,533 | 1111 1111 1111 1101 | 1110 1111 10 1111 11 10 111101 | EF BF BD | ||
Nem karakterek | U + FFFE | 65,534 | 1111 1111 1111 1110 | 1110 1111 10 1111 11 10 111110 | EF BF BE | |
U + FFFF | 65,535 | 1111 1111 1111 1111 | 1110 1111 10 1111 11 10 111111 | EF BF BF | ||
Szöveg | ? | U + 10 000 | 65,536 | 1 0000 0000 0000 0000 | 11 110 000 10 01 0000 10 0000 00 10 000000 | F0 90 80 80 |
? | U + 1D11E | 119,070 | 1 1101 0001 0001 1110 | 11 110 000 10 01 1101 10 0001 00 10 011 110 | F0 9D 84 9E | |
? | U + 1FFFD | 131,069 | 1 1111 1111 1111 1101 | 11110 000 10 01 1111 10 1111 11 10 111 101 | F0 9F BF BD | |
Nem karakterek | U + 1FFFE | 131,070 | 1 1111 1111 1111 1110 | 11110 000 10 01 1111 10 1111 11 10 111 110 | F0 9F BF BE | |
U + 1FFFF | 131,071 | 1 1111 1111 1111 1111 | 11 110 000 10 01 1111 10 1111 11 10 111111 | F0 9F BF BF | ||
Szöveg | ? | U + 20 000 | 131,072 | 10 0000 0000 0000 0000 | 11 110 000 10 10 0000 10 0000 00 10 000000 | F0 A0 80 80 |
? | U + 2FFFD | 196,605 | 10 1111 1111 1111 1101 | 11110 000 10 10 1111 10 1111 11 10 111 101 | F0 AF BF BD | |
Nem karakterek | U + 2FFFE | 196,606 | 10 1111 1111 1111 1110 | 11110 000 10 10 1111 10 1111 11 10 111 110 | F0 AF BF BE | |
U + 2FFFF | 196,607 | 10 1111 1111 1111 1111 | 11 110 000 10 10 1111 10 1111 11 10 111111 | F0 AF BF BF | ||
... egyéb tervek fenntartva ... | ||||||
Különlegességek | ? | U + E0000 | 917,504 | 1110 0000 0000 0000 0000 | 11110 011 10 10 0000 10 0000 00 10 000000 | F3 A0 80 80 |
? | U + EFFFD | 983,037 | 1110 1111 1111 1111 1101 | 11110 011 10 10 1111 10 1111 11 10 111101 | F3 AF BF BD | |
Nem karakterek | U + EFFFE | 983,038 | 1110 1111 1111 1111 1110 | 11110 011 10 10 1111 10 1111 11 10 111110 | F3 AF BF BE | |
U + EFFFF | 983,039 | 1110 1111 1111 1111 1111 | 11110 011 10 10 1111 10 1111 11 10 111111 | F3 AF BF BF | ||
Magán felhasználás | [?] | U + F0000 | 983,040 | 1111 0000 0000 0000 0000 | 11110 011 10 11 0000 10 0000 00 10 000000 | F3 B0 80 80 |
[ ] | U + FFFFD | 1 048 573 | 1111 1111 1111 1111 1101 | 11110 011 10 11 1111 10 1111 11 10 111101 | F3 BF BF BD | |
Nem karakterek | U + FFFFE | 1 048 574 | 1111 1111 1111 1111 1110 | 11110 011 10 11 1111 10 1111 11 10 111110 | F3 BF BF BE | |
U + FFFFF | 1,048,575 | 1111 1111 1111 1111 1111 | 11110 011 10 11 1111 10 1111 11 10 111111 | F3 BF BF BF | ||
Magán felhasználás | [?] | U + 100 000 | 1 048 576 | 1 0000 0000 0000 0000 0000 | 11110 100 10 00 0000 10 0000 00 10 000000 | F4 80 80 80 |
[?] | U + 10FFFD | 1,114,109 | 1 0000 1111 1111 1111 1101 | 11110 100 10 00 1111 10 1111 11 10 111101 | F4 8F BF BD | |
Nem karakterek | U + 10FFFE | 1,114,110 | 1 0000 1111 1111 1111 1110 | 11110 100 10 00 1111 10 1111 11 10 111110 | F4 8F BF BE | |
U + 10FFFF | 1,114,111 | 1 0000 1111 1111 1111 1111 | 11110 100 10 00 1111 10 1111 11 10 111111 | F4 8F BF BF |
Bármely, az UTF-8-ban kódolt karakterláncban észrevesszük, hogy:
A legnagyobb pontján érvényes kód hozzárendelhető érvényes karakter nem magán az U + EFFFD a 15 th Terv (ez még nincs kijelölve, de válhat a jövőben), de UTF-8 is használható, szabványos módon, bármely érvényes karakter képviseletére magáncélú használatra (az U + E000 - U + F8FF, U + F0000 - U + FFFFD és U + 100000 - U + 10FFFD három tartomány egyikében).
Az, hogy nem karaktereket vagy magáncélú karaktereket fogadunk- e el, az alkalmazások vagy a szövegátviteli protokollok feladata. A nem karaktereket azonban általában nem fogadják el azok a szövegek, amelyek szigorúan megfelelnek az Unicode szabványnak vagy az ISO / IEC 10646 szabványnak .
Egyes alkalmazások további korlátozásokat vetnek fel a használható kódpontokra (például a HTML és az XML szabványok minden, az előírásoknak megfelelő dokumentumban tiltják a legtöbb vezérlő karakter jelenlétét U + 0000 és U + 001F és U + között. A 0080 és az U + 009F, az U + 0009 fülvezérlőn kívül, üres karakternek tekinthető, és a nem karaktereket is tiltja ).
Bármely kódpontot pontosan ugyanaz a bináris szekvencia képvisel, függetlenül attól, hogy a szövegben milyen relatív helyzetben van, és ezek a szekvenciák automatikusan szinkronizálódnak a jelentős kódpontok osztatlan helyzetén (itt a bájtok: mindig megtudhatjuk, hogy egy bájt megkezdődik-e vagy sem. hatékony bináris szekvencia); ez a kódolás tehát lehetővé teszi a gyors szövegkereső algoritmusok, például a Boyer-Moore algoritmus használatát .
Nem mindig ez a helyzet a kontextuális kódolásokkal (amelyek általában adattömörítést használnak , például az Unicode szabványt kiegészítő, opcionális UTS szabvány 6. számú műszaki megjegyzésében meghatározott SCSU-t ), és amelyek megkövetelhetik a szöveg elejétől való teljes elolvasását. egynél több állapotváltozón (vagy amelyek további redundancia-kódokat tartalmaznak); legjobb esetben ezeknek a kódolásoknak összetett újraszinkronizációs algoritmusok használatára lehet szükség, gyakran heurisztikákon alapulva, amelyek kudarcot vallanak, vagy hamis értelmezéshez vezethetnek, ha a szöveget nem a kezdetektől olvasják (pl. BOCU -1).
A kódolás elve és egyediségeA fenti táblázatban azt látjuk, hogy az „€” karakter az U + 20AC kódpontban található, akár 8364-es tizedesjegyben, akár binárisan: 100 000 10101100.
Ez az utolsó szám jelentős bináris számjegyekkel rendelkezik, ezért legalább 14 bitre van szükség az "€" karakter kódolásához. A fent bemutatott szabvány valójában három bájtot igényel e karakterek ábrázolásához.
Négy bájt rendelkezésre állása esetén akár 21 bitet is el lehetne helyezni ennek a szabványnak megfelelően , így különösen az „€” karaktert kell megjeleníteni 00000 00 100000 10101100-ig, hozzáadva 7 kezdő nullát . Ugyanakkor a szabvány előírja, hogy az UTF-8 dekódoló program biztonsági okokból nem fogadhat el feleslegesen hosszú bájtos karaktersorozatokat, mint ebben a példában (kerülje a túl toleráns alstringek használatát). Így az „€” kód: 11100010 10000010 10101100, de a 21 biten szereplő „€” ábrázolásból levezetett 11110000 10000010 10000010 10101100 kódot nem szabad használni, bár egyértelmű.
Az ilyen, a szükségesnél hosszabb formát angolul overlongnak nevezik . Az ilyen formanyomtatványokat (eredetileg régi specifikációkban engedélyezték, mielőtt az X / Open Consortium , majd ezzel párhuzamosan az ISO 10646 és az Unicode szabvány által közzétett kezdeti RFC szabványosította volna egymást ) tilos, és érvénytelennek kell tekinteni.
A kódolás prediktív, és mindig lehetővé teszi a kódpontot képviselő szekvencia első bájtjának helyzetének megkeresését bármelyik bájt értékéből és korlátozott számú szomszédos bájt olvasásából a két olvasási irányban (ez mindig maga a bájt lesz, vagy az első jogosult az 1-3 szomszédos bájt egyikében ).
Az ilyen szekvenciákat állítólag rosszul alakítják ki . (Lásd a fenti hivatkozást, különösen a szabvány D36 megfelelőségi záradékának második táblázatát vagy az Unicode cikket ).
Másrészt a fenntartott (a karakterekhez még nem rendelt) kódpontok engedélyezettek (még akkor is, ha a karakterek értelmezése félreérthető maradhat): az alkalmazások feladata eldönteni, hogy ezek a karakterek elfogadhatóak-e vagy sem, tudva, hogy ugyanazok a karakterek elfogadhatók-e vagy sem. az alkalmazásokat valószínűleg továbbra is használni fogják, annak ellenére, hogy ezeket a pozíciókat az Unicode és az ISO 10646 szabványokban új, teljesen érvényes karakterekhez rendelték.
Hasonlóképpen, az egyéb „ nem karakterekhez ” állandóan hozzárendelt más kódpontok tilosak az ISO / IEC 10646 vagy az Unicode szabványnak megfelelő szövegekben : például U + x FFFE - U + x FFFF (ahol x hexadecimális tervszámot jelent 0-10). De továbbra is kódolhatóak és dekódolhatók az UTF-8-ban ( nem karakterek állnak rendelkezésre az alkalmazások számára, amelyek felhasználhatják őket a belső API-kban, például köztes kódokként, amelyek szükségesek bizonyos folyamatok végrehajtásához.)
A korlátozás a reprezentációs tér csak kódpontokat kisebb vagy egyenlő U + 10FFFF (ide nem értve a kódpontokat rendelt félig kódpontokat ) nem mindig alkalmazták:
Az US-ASCII szöveget azonos módon kódolják az UTF-8-ban (ha a BOM- ot nem használják).
Mivel egy karakter bájtsorozatra van felosztva (nem több bájtos szavakra), nincs problémás endianitás ( angol endianness ).
A legtöbb latin nyelv esetében a digitális adatfájlok vagy a program forráskódjai, vagy sok szöveges kommunikációs protokoll (például FTP , HTTP vagy MIME ), amelyek kiterjedten (vagy néha csak részenként) használnak karaktereket. Az US-ASCII, UTF-8 kevesebbet igényel bájt, mint az UTF-16 vagy az UTF-32 .
Számos, egyetlen egybájtos karakterrel érvényes számítógépes programozási technika továbbra is érvényes marad az UTF-8 esetében, beleértve:
Ez egy önszinkronizáló kódolás (egyetlen bájt elolvasásával tudjuk, hogy ez egy karakter első-e vagy sem).
A kódpontokat az UTF-8-ban különböző méretű bájtsorozatok képviselik (csakúgy, mint az UTF-16-ban), ami bonyolultabbá teszi egyes műveleteket a kódpontok húrjain: a kódpontok számának kiszámítását; pozícionálás egy megadott távolságban (a kódpontok számában kifejezve) egy szöveges fájlban, és általában minden olyan művelet, amely hozzáférést igényel az lánc N pozíciójának kódpontjához.
A karakterláncok változó mérete megakadályozza a hatékony algoritmusok használatát a húrok összehasonlításában, mint például a Knuth-Morris-Pratt algoritmus, és ezért erősen bünteti a tömeges adatfeldolgozást, mint a kihasználtsági adatbázisokban. Ez a probléma azonban inkább a szabványosítás, mint a kódolás szempontjaival függ össze .
Az US-ASCII- n kívül sok karaktert használó nyelvek esetében az UTF-8 lényegesen több helyet foglal el. Például az ázsiai nyelvű szövegekben, például a kínai vagy a japán nyelvben ( például kandzsi ) használt általános ideogrammok 3 bájtot használnak az UTF-8-ban, míg az 2 bájtot az UTF-16-ban.
Általánosságban elmondható, hogy azok az írások, amelyek sok, U + 0800 értékű vagy annál nagyobb értékű kódpontot használnak, több memóriát foglalnak el, mintha UTF-16-tal kódolták volna őket (az UTF-32 csak azoknál a szövegeknél lesz hatékonyabb, amelyek főleg írásokat használnak. régi vagy ritka kódolású, az alapvető többnyelvű terven kívül, vagyis U + 10000-tól, de bizonyos folyamatokban lokálisan is hasznosnak bizonyulhat az algoritmusok egyszerűsítése érdekében, mert az ott lévő karakterek mindig rögzített méretűek, konvertáló bemenet vagy kimenet az UTF-8 vagy UTF-16 vagy onnan történő adatai triviálisak).
Kódolási rendszere révén lehetséges volt egy kód különbözőképes ábrázolása az UTF-8-ban, ami biztonsági problémát vethet fel: egy rosszul megírt program elfogadhat bizonyos számú UTF-8 reprezentációt, amely az RFC 3629 szerint általában érvénytelen. valamint az ISO 10646 és az Unicode által közzétett (ma már egymással egyenértékű) előírásokban; de az eredeti specifikáció szerint nem ez volt a helyzet, ami lehetővé tette, hogy egyetlen karakterként konvertálják őket.
Így egy bizonyos karakterláncokat észlelő szoftver ( például az SQL-injekciók megakadályozása érdekében ) kudarcot vallhat a feladatában (ez már nem így van, ha ellenőrizzük, hogy a kódolás megfelel-e az UTF-8 szigorú és szabványos meghatározásának. minden).
Nézzünk egy példát egy valódi vírus esetében támadó HTTP szerverek a Web in 2001 ( (en) Crypto-Gram: július 15, 2000 Microsoft IIS és PWS Extended Unicode könyvtár bejárás biztonsági rés a Microsoft IIS 4.0 / 5.0 Web Directory bejárási biztonsági rés ) . A detektálható szekvenciát az ASCII-ben ( a fortiori az UTF-8-ban) "/../" képviselheti a " 2F 2E 2E 2F " bájt hexadecimális jelöléssel . Ennek a karakterláncnak az UTF-8 kódolásának hibás módja azonban " 2F C0 AE 2E 2F ", más néven túl hosszú . Ha a szoftvert nem gondosan írják meg, hogy elutasítsák ezt a láncot, például kanonikus formába állítva, akkor potenciális biztonsági megsértés nyílik meg. Ezt a támadást könyvtár bejárásnak hívják .
Az UTF-8 kódolású szöveget elfogadó szoftvereket árnyékolták, hogy szisztematikusan elutasítsák ezeket a hosszú űrlapokat, mert nem felelnek meg a szabványnak: vagy a teljes szöveget elutasítják; de néha az érvénytelen szekvenciákat helyettesítő karakter váltja fel (általában U + FFFD, ha az alkalmazás ezt a karaktert normálisan elfogadja és feldolgozza; néha kérdőjel vagy az ASCII SUB U + 001A helyettesítő vezérlő karaktere , amely más kompatibilitási problémákat vethet fel); ritkábban ezeket a tiltott szekvenciákat csendben megszüntetik (ami nagyon kevéssé ajánlott).
Az UTF-8 csak a null vezérlő karaktert (U + 0000) reprezentálhatja egyetlen null bájttal, ami kompatibilitási problémákat vet fel azoknak a karakterláncoknak a feldolgozásával, amelyek nem külön kódolják a tényleges hosszukat, mert ez a null bájt nem akkor jelöl karaktert, hanem a a karakterlánc vége (nagyon gyakori eset C vagy C ++ nyelven és az operációs rendszerek API-jaiban). Ha az ilyen rendszerek szövegében null karaktert kell tárolni, akkor az így átalakított szöveget az UTF-8-ba kell kódolni, mielőtt erre a nyelvre vagy rendszerre specifikus menekülési rendszert használnánk. A gyakorlatban egyetlen érvényes szöveg sem tartalmazhatja ezt a karaktert. Egy másik megoldás az, hogy a szokásos UTF-8 kódolásban tiltott szekvenciák egyikét használjuk a karakter kódolásához ezzel a szekvenciával; de az így kódolt szöveg nem fog megfelelni a szokásos UTF-8 kódolásnak, még akkor sem, ha az így módosított kódolás megfelelő konform univerzális transzformációs formátum marad (amelyet azonban nem szabad UTF-8-nak jelölni). Lásd az alábbi részt az UTF-8 alapú nem szabványos változatokról.
Az UTF8, mint bármely változó hangmagasságú kódolás használata az adatbázisban több teljesítményproblémát vet fel.
Az összehasonlító műveleteket (=,>, <, BETWEEN, LIKE ...), rendezést (ORDER BY), csoportosítást (GROUP BY), mint például az információk szemantikáján alapuló deduplikációs műveleteket (DISTINCT) lehetetlen közvetlenül kezelni az UTF8-ban .
Ugyanazon betűket tartalmazó karakterláncok esetében (például CHAR (8)) a bájtok száma eltérő lehet (különösen a diakritikus karakterek miatt: ékezetek, ligatúra ...), a használt algoritmusoknak például többnyire végezzen egy összehangolást a működés megkezdése előtt, ami nem elhanyagolható további feldolgozási költséget okoz.
Például a MySQL / MariaDB DBMS úgy döntött, hogy az UTF8 formátumú karakterláncok karaktereit reprezentálja, szisztematikusan 3 bájtot használva karakterenként. A következmények a következők: az adatok mennyiségének megháromszorozása és az indexkulcsok potenciális hosszának hárommal való elosztása az ASCII kódoláshoz képest, valamint a végrehajtási idők meghosszabbítása összehasonlítás, rendezés, csoportosítás vagy deduplikáció esetén. A karakterlánc végül UTF8 formában kerül visszaadásra a felesleges bájtok megtisztítása után.
Más DBMS-k, mint például a Microsoft SQL Server, úgy döntöttek, hogy tömörítik az UTF8-támogatást úgy, hogy a további karaktereket egy 2 bájtos kódolásba helyezik be, az UNICODE alapján, kihasználva a specifikáció által üresen hagyott szóközöket. Az UTF8-ba történő fordítás további erőfeszítése csak a 2 bájton kódolt karakterek újrakódolásában és a 3-on kódoltak bővítésében rejlik.
Az UTF-8-at Kenneth Thompson találta ki egy vacsora alkalmával Rob Pike körül1992. szeptember. Akkor FSS-UTF-nek hívták , és azonnal felhasználta azt a Plan 9 operációs rendszerben, amelyen dolgoztak. Az egyik megoldandó kényszer a null és '/' karakterek kódolása volt, mint az ASCII-ben, és hogy egyetlen másik karaktert kódoló bájtnak sem ugyanaz a kódja. Így a UNIX operációs rendszerek szoftver adaptáció nélkül folytathatták a két karakter keresését egy karakterláncban.
Az FSS-UTF egy 1993-as előzetes X / Open szabvány tárgyát képezte, amelyet az ISO javasolt. Ez utóbbi az ISO / IEC 10646 szabvány részeként fogadta el először UTF-2, majd végül UTF-8 néven.
Grafikon, amely bemutatja az UTF-8 (világoskék) használatát, meghaladva a többi fő szöveges karakterkódolást az interneten. 2010-re az UTF-8 prevalenciája 50% körül volt, 2016-ban viszont inkább 90%. |
A webhelyeken használt technológiákat tükröző statisztikák, amelyeket a különböző minták felismerési technikái alapján határoztak meg, beleértve a HTML elemeket, a meghatározott HTML címkéket (például a "generátor meta" címkét, a JavaScript kódot, a CSS kódot, a webhely URL-jének struktúráját, webhelyen kívüli linkek, HTTP fejlécek, például cookie-k, HTTP válaszok bizonyos kérésekre, például tömörítésre.
A statisztikák az Alexa szerint a legjobb 10 millió webhely mintáján alapulnak . Az összes nem éri el a 100% -ot, mert egyes szerverek egynél több technológiát használnak. |
Forrás w3techs |
Az eredeti FSS-UTF kódolás célja az volt, hogy az eredetileg az ISO 10646 által javasolt UTF-1 multibyte kódolást helyettesítse. Ez az eredetileg megengedõ kódolás több bináris reprezentációt tett lehetõvé ugyanannak a karakternek (ezt az X / Nyílt konzorcium, Kenneth Thompson jóváhagyásával).
Ezen kívül tudott (egy előzetes változatát nem marad meg) kódolják az összes karakter, amelynek kódját pont, amely érték akár 32 bit meghatározásával egy nyolcadik típusú byte (a szekvencia, amely legfeljebb 6 byte ), a helyett a 7 fajta a a kódoláshoz végül megtartott bájtok (akár 6 bájtból álló szekvenciákban is ) csak a kód mutat 31 bitig az UTF-8 kezdeti verziójában (amelyet a Consortium X / Open publikált FSS-UTF néven, majd a az ISO 10646 technikai bizottság, mint „UTF-2” javaslat, akkor még versenyben van az „UTF-1” javaslattal, mindaddig, amíg az UTF-2 javaslatot megtartják, és elfogadják az X / Open rendszerben már megtartott és használt UTF-8 nevet, és 9. terv).
Ezt az UTF-8 kódolást tovább korlátozták, amikor az Unicode és az ISO 10646 megállapodtak abban, hogy csak az első 17 síkban osztanak ki karaktereket annak érdekében, hogy korlátlan ideig fenntartsák az UTF-16-tal való kompatibilitást (anélkül, hogy módosítanák kellene őket), a szekvenciákat csak 4 bájtig korlátozva és a 7 bájttípus közül csak az első 5-öt használja (ami érvénytelen új bájtértékek és bizonyos bájtsorozatok megadását tette szükségessé).
Az IETF most van szükség UTF-8 által támogatott alapértelmezett (és nem csak, mint egy kiterjesztése támogatott) az összes új kommunikációs protokollok az interneten (megjelent a RFC számmal), aki cserébe a szöveget (a legrégebbi protokollok azonban nem módosultak hogy ezt a támogatást kötelezővé tegyék, de csak akkor bővítsék, ha lehetséges, támogassák opcionálisan, ha ez inkompatibilitást eredményez vagy új biztonsági kockázatokat hoz létre: ez a helyzet az Internet protokolljaival , amelyeket kezdeti verzióiban széles körben használnak DNS- ként , HTTP- ként , FTP- ként , Telnetként és HTML- ként. akkor még nem szabványosította a W3C és az ISO).
Elengedhetetlenné vált, különösen a fő webkommunikációs szoftverekben és a mai operációs rendszerekben:
Ugyanakkor az UTF-8 változatait (a kezdeti korlátlan verzió kódolási lehetőségei alapján) továbbra is használták (nevezetesen a Java karakterlánc-sorozatosítás megvalósításakor), hogy lehetővé tegyék a kódolást a. bájt (például a null karakter).
Ezenkívül egyes rendszerek korlátlan karakterláncokat használnak: például a Java (és más nyelvek, beleértve a C, PHP, Perl stb. Karakterlánc-manipulációs könyvtárakat) olyan karaktereket képviselnek, amelyek kódolási egysége 16 bit (ez lehetővé teszi a karakterláncok UTF használatával történő tárolását) -16 kódolás, de az UTF-16 által tiltott értékekre és párosításra vonatkozó "félkódok" vagy helyettesítők sorrendjében érvényességi korlátok nélkül ; ebben az esetben a kódoló egységeket bináris értékként kezeljük, és külön-külön szükséges sorosítani őket (függetlenül karakterektől vagy kód félpontoktól való lehetséges értelmezésüktől). Ebben az esetben minden olyan 16 bites kódoló egység , amely "karaktert" jelent (nem korlátozott), soros formában, legfeljebb 3 bájtból álló szekvenciák formájában jelenik meg , és néhány, a megvalósítás által tiltott bájt (például null karakter vagy törtrész). / 'fájlrendszerben vagy más egybájtos karakterek más protokollokban) kettős bájtos menekülési szekvenciákká vannak kódolva, amelyek egyike sem nulla, egyszerűen az FSS-UTF első specifikációjának kódolási elvével (mielőtt az X megtartotta volna). / Nyílt konzorcium a kezdeti RFC-ben, ahol ezeket a meneküléseket kifejezetten tiltották és továbbra is így maradtak).
Az UTF-2-re megtartott UTF-2 javaslat elfogadása előtt volt egy UTF-1 variáns is, ahol többféle kódolás nem volt lehetséges, de az egyes bájtok helyzetének figyelembevétele érdekében nehezebb kódolást / dekódolást igényelt. számos "mágikus" érték.
Ezeket a variánsokat nem szabad "UTF-8" -nak nevezni.
Ezen nem szabványos változatok egyike azonban későbbi szabványosítás tárgyát képezte (az UTF-16 alternatívájaként és 3 bájton kódolt "félkód" párok használatával, azaz 4 helyett 6 bájtot használunk . a UTF-8): lásd a Cesu-8 .
Példa a Java-ban használt variánsraPéldául a Java virtuális gépek integrációs API-jai (JNI, Java Native Interface vagy előre lefordított osztályok sorosításához), amelyek lehetővé teszik a nem korlátozott Java karakterláncok cseréjét bájtsorozatok formájában (manipulálásuk, használatuk vagy előállításuk céljából). natív kóddal, vagy bájt karakterláncokba kódolt natív fájlként történő tárolásra), az "UTFChars" vagy "UTF" utótaggal látja el, de ez a Java-specifikus kódolás nem UTF-8 (a Sun dokumentációja módosított UTF-nek nevezi , de néhány régebbi JNI-dokumentum még mindig helytelenül nevezi ezt a kódolást UTF-8-nak , ami néhány natív JNI-könyvtár viselkedési rendellenességeket okozott, különösen a rendszer API-kkal. régebbi natív platformok, amelyek nem támogatják natív módon a 8 bit feletti karakterkódolásokat ), mert:
Következésképpen:
Ezek a folyamatok nem hatékonyak nagy mennyiségű szöveg összekapcsolására, mivel további memóriapufferek elosztására van szükség, hogy natív kódban csatlakozzanak olyan rendszer- vagy hálózati interfészekhez, amelyek csak a szabványos UTF-8-ot fogadják el.
Azonban a JNI hatékonyabb bináris API-t is biztosít, amely lehetővé teszi az UTF-16 közvetlen használatát, amely közvetlenül képes kapcsolódni az UTF-16-ot támogató hálózati protokollokkal és rendszerinterfészekkel (pl. Windows API-k), anélkül, hogy további memóriafoglalást igényelne az átkódoláshoz (csak a megfelelőség ellenőrzésre lehet szükség, főleg a kódolt szövegben a félkód vagy a helyettesítő helyes párosításának ellenőrzése érdekében , amelyet a Java (csakúgy, mint más programozási nyelvek) érvényességi korlátozás nélkül engedélyez manipulálni saját karakterláncaiban, amelyek nem csak szövegek tárolására szolgálnak megfelel az UCS-nek). Ezt a bináris API-t minden olyan rendszer támogatja, ahol a Java portot kapott, még azokban is, amelyek operációs rendszere nem kínál Unicode szöveges API-t (a támogatás elérhető a gazdagép natív alkalmazásában, vagy a JVM vagy más független natív natív könyvtárak használatával. könyvtárak.