utf-16
utf-16 er et 16-biters kodesystem med variabel lengde, og det bruker utf-tegnsettet for tegnkodepunkter. Dette betyr at ET utf-16-kodet tegn vil ha en 16-biters kodeenhet.
Som vi vet at ET utf-8-kodet tegn kan representeres i 1 til 4 kodeenheter, kan ET utf-16-tegn representeres i 1 eller 2 kodeenheter. Derfor kan ET utf-16-tegn ta 16 eller 32 biter minne basert på kodepunktet.
før du hopper inn i utf-16 koding spesifikasjoner, la oss forstå hvordan VI kan gjøre UTF-16 arbeid.
Siden vi har 16-biters kodeenhet, kan vi i teorien kode 21 i tegn fra kodepunkt 0 til 65,535. Men hva om vi har et tegn med kodepunktet større enn 65,535? I sa fall kan vi legge til en annen kodeenhet.
med den ekstra kodeenheten kan vi kode totalt 232 tegn som er MER ENN 4M. Men så er spørsmålet hvordan EN utf-16 dekoder vil vite at den må vurdere 2 kodeenheter for å dekode et tegn?UTF-8 løste dette problemet ved å sette innledende biter av den første kodeenheten og fortsettelseskodeenhetene til noen spesifikke bitverdier som EN utf-8 dekoder kan bruke til å trekke fra hvor mange kodeenheter et tegn kan ta.
Vi kan gjøre Det samme med utf-16 kodeenheten, men da må vi ofre noen biter i en kodeenhet for denne funksjonen. Vi kan sette noen innledende biter av en kodeenhet til en meningsfull verdi som EN utf-16 dekoder kan forstå.
også for å gi selvsynkroniserende kraft til kodeenheter, må en kodeenhet kunne fortelle om det er den første kodeenheten eller en fortsettelseskodeenhet og ikke et tegn på bare en kodeenhet.Så Unicode bestemte seg For å ofre de første 6 bitene av kodeenheten, slik at bare 10 biter for å kode kodepunktet til et tegn per kodeenhet. Hvis et tegn trenger 2 kodeenheter, inneholder 20 biter av minnet (ut av 32 biter eller 4 byte) den faktiske kodepunktinformasjonen til tegnet.
Så hva er disse første bitene og hvordan disse bitene gjør en pute i utf-tegnsettet? La oss følge eksemplet nedenfor.
1101 10xx xxxx xxxx 1101 11xx xxxx xxxx
FIRST CODE UNIT---- SECOND CODE UNIT---
fra utf-16-standarden skal den første kodeenheten starte med 110110₂ og den andre kodeenheten skal starte med 110111₂. Dette vil hjelpe EN utf-16 dekoder til å forstå hvilken hvis den første kodeenheten og hvilken som er den andre. Dette gjør utf – 16 selvsynkronisering.
Nå hva vi har 10 biter per kodeenhet å leke med, hva er rekkevidden vi kan spille innenfor? Til slutt, hvor mange tegn kan kodes i to kodeenheter AV utf-16-koding?
ikke bekymre deg, vi vil snakke om tegn kodet i bare en kodeenhet.
hvis du ser på kodeenhetsmalene ovenfor, har vi et område fra 1101 1000 0000 0000₂ til 1101 1111 1111 1111 1111. Det er ekvivalent Med D800 ~ ~ Pos = Headcomp Til Dfff ~ ~ POS = HEADCOMP.
💡 den første kodeenheten har området Fra D800 År Til 6fffuzzi, og den andre kodeenheten har området FRA DC00 ÅR til DFFFITIUS. Vi kan få disse verdiene ved å slå alle kodepunkter biter: på og av.
siden UTF-16 må være selvsynkronisering, må kodepunkter Mellom D800itius og DFFFASCRIPT ikke representere et tegn I utf-16. Siden alle utf-kodinger følger samme utf-tegnsett, er disse kodepunktene begrenset av UTF, og de er ikke og vil ikke bli tildelt noen tegn.
Kodepunkter Mellom D800itius Og DFFFUZZI representerer ikke noen tegn derfor de kalles surrogat kodepunkter eller sammen de er også kalt som surrogat par⁰.
det første surrogatkodepunktet (fra første kodeenhet) kalles også som høy surrogat og andre kodepunkt (fra andre kodeenhet) kalles også som lav surrogat. Gjør totalt 2048 kodepunkter, 1024 per surrogat.
💁 ♂ surrogatkodepunkter ofret sine liv slik at vi kunne kode flere tegn med to kodeenheter. Tenk på det!
Så det store spørsmålet, kan vi kode et tegn med en enkelt kodeenhet AV UTF-16? Svaret er JA. UTF-16 er en 16-bit variabel lengde koding ordningen. Så betyr det at vi kan kode 21@-tegn med en enkelt kodeenhet?
svaret ER NEI. I teorien, vi kunne kode 21 ① tegn med kodepunkt 0000 ^ film (0^^) TIL FFFF ^ FILM (65535^), men kodepunkter Mellom D800 ^ Film og DFFF ^ FILM representerer ikke noen tegn som de er reservert.
Derfor er det trygt å kode tegn fra 0000₁₆ å D7FF₁₆ og E000₁₆ å FFFF₁₆ forlater hvilke kontoer for å 63,488 (65536-2048) tegn. Dette er bare for tegnene som kan kodes i bare en kodeenhet AV UTF-16.
Siden vi har totalt 20 biter å leke med når det gjelder tegn enn det som kan kodes i 2 kodeenheter AV UTF-16, kan vi kode 22⁰ flere tegn, som er 1.048.576 tegn.
Så totalt kan vi kode 1,048,576 + 63,488 som utgjør 1,112,064 tegn (mer enn 1Million tegn). Dette er grensen for utf-tegnsettet. Siden utf-16 kan kode disse mange tegnene, kan andre utf-kodinger ikke representere tegn utover disse.
Utf charset Code Points
Som vi vet at et kodepunkt er en desimalverdi tildelt et tegn, må Vi (Unicode) ikke tildele et ugyldig kodepunkt til et faktisk tegn. Så langt er de ugyldige kodepunktene surrogatkodepunkter.Med bare en enkelt utf-16 kodeenhet, kan vi kode 63,488 tegn som spenner fra 0000 ~ ~ pos = headcomp ~ ~ pos = headcomp ~ ~ pos = headcomp fra 0ff ~ ~ POS = headcomp TIL D7FF ~ ~ ~ POS = HEADCOMP OG E000 ~ ~ Pos = Headcomp Til FFFF ~ ~ POS = HEADCOMP. Det siste kodepunktet er 65.535. Disse kalles BMP-tegn(forklart senere).
med to kodeenheter AV UTF-16 kan vi kode 1.048.576 tegn. Siden vi ikke igjen kan starte fra 0 verdi (kodepunkt) fordi disse kommer ETTER BMP-tegn, må vi kompensere dem med 65,536. Disse tegnene kalles Supplerende tegn(forklart senere).
Derav den første tilleggskarakter har en kodepunktverdi på 65536, noe som tilsvarer 10000itius. Siden vi kan kode 1.048.576 tegn med to kodeenheter AV UTF-16, er det siste kodepunktet 1114111, noe som tilsvarer 10FFFFITIUS.
Så la oss bryte ned ting i en enkel tabellform.
+-----------+---------------------+--------------------+
| UTF-16 CU | Code Point | |
+-----------+---------------------+--------------------+
| 1 | 0000₁₆ - D7FF₁₆ | valid |
+-----------+---------------------+--------------------+
| 1 | D800₁₆ - DFFF₁₆ | invalid(surrogate) |
+-----------+---------------------+--------------------+
| 1 | E000₁₆ - FFFF₁₆ | valid |
+-----------+---------------------+--------------------+
| 2 | 10000₁₆ - 10FFFF₁₆ | valid |
+-----------+---------------------+--------------------+
| | 110000₁₆ - FFFFFF₁₆ | unassigned |
+-----------+---------------------+--------------------+
med denne kunnskapen, La oss se hvordan vi kan kode noen tegn i utf-16. La oss velge et enkelt ASCII-tegn A (kodepunkt: 41uzzi), et tegn Fra Hindi (Indisk) språk आ (uttalt Som Aa, kodepunkt: 906itius) og et uttrykksikon 😊 (kalt Som Lykkelig ansikt, kodepunkt: 1f60aitius).
som vi kan se fra tabellen ovenfor, kan Både a og आ bli kodet i bare en kodeenhet AV UTF-16 siden deres verdier er mindre ENN FFFFITIUS.
når vi må kode et tegn i bare en kodeenhet, må vi bare konvertere kodepunktet til tegnet i et 16-biters binært tall. For tegnene A er 00000000 01000001₂ UTF – 16-representasjonen.
På Samme måte, for tegnet आ, vi trenger bare å konvertere sin kodepunkt 906itius til en 16-bit binært tall som er 00001001 00000110₂.
Normalt representerer vi kodeenheter av et tegn i heksadesimale tall. Derfor for karakter A, DEN UTF-16 representasjon er 0041itius og på samme måte, for tegnet, UTF-16 representasjon आ er 0906itius.
for tegnet 😊 er ting litt annerledes. Dens kodepunkt ER 1F60AITIUS. Hvis vi ser på utf-16-tabellen nevnt ovenfor, må den kodes i 2 kodeenheter AV UTF-16. Så hvordan begynner vi?
Først må vi trekke fra 10000uzzi fra kodepunktet. Grunnen til det er, hver karakter kodet i 2 kodeenheter AV UTF-16 har kommet etter BMP tegn hvis siste kodepunkt ER FFFFITIUS.
Derfor for å få den faktiske verdien av biter som brukes for koding (som er 20 i 2 kode enheter), må vi trekke fra 10000inois fra kodepunktet og bruke det endelige tallet for å generere disse 20 biter.
💡 for å hjelpe deg å forstå bedre, vil det første tegnet representert med 2 kodeenheter AV UTF-16 ha alle sine 20 biter satt til 0. Så verdien av bitene som brukes til å kode kodepunktet til denne karakteren er 0. Men fortsatt, er dens kodepunkt 10000inois ifølge Unicode tegnsett. Dette er fordi verdien gitt av disse 20 bitene er lagt til 10000itius å generere den endelige kodepunktet.
som sett tidligere ser disse 2 kodeenhetene ut som nedenfor.
1101 10xx xxxx xxxx 1101 11xx xxxx xxxx
FIRST CODE UNIT---- SECOND CODE UNIT---
Vi trenger bare å fylle disse 20 bitene (x
) med verdien mottatt fra tegnkodepunktet. Kodepunktet for tegnet 😊er 1F60AITIUS. Men først må vi trekke fra 10000inois fra det. Vi får F60AITIUS.
nå må vi konvertere F60AITIUS til en 20-bit binært tall og fylle 20 biter i ovennevnte kode enhet mal. F60AITIUS i binær er 0000111101 1000001010₂. Nå kan vi fylle disse 20 plassholderbitene.
Nedenfor er de endelige kodeenhetene.
1101 1000 0011 1101 1101 1110 0000 1010
0xD83D 0xDE0A
den raske måten å sjekke om disse kodeenhetene er gyldige og faktisk hvis disse surrogatparene kan representere det kodede tegnet, åpner Du En Nettleser DevTool og skriver inn console.log('\uD83D\uDE0A');
i konsollen.
du kan også bruke dette nettbaserte verktøyet til å generere utf-16 kodepunkter.
Unicode Character Planes
et fly er en sammenhengende gruppe på 21% eller 65 536 kodepunkter. Siden utf-16 har begrenset kode poeng til maksimalt 10ffffitius, har vi totalt 17 tegn fly I Unicode standard fra 0 til 16.
Siden 21 fremover-tegn kan defineres av enkeltkodeenheten TIL UTF-16 (inkludert surrogatkodepunkter), danner den det første (0.) planet. Dette flyet inneholder nesten alle tegnene i grunnleggende språk rundt om i verden. Dette er grunnen til at dette flyet kalles Basic Multilingual Plane eller BMP.
Deretter har vi kodepunkter definert av TO kodeenheter AV UTF-16. Disse inneholder 22⁰ tegn som vi har 20 biter for å kode kodepunktverdien. Disse er delt inn i 16 fly (2 igjen x 21 mer). Disse kalles supplerende fly.
💡 for mer informasjon om disse flyene, les Dette Wikipedia-dokumentet.
Sammenligning MED UCS-2
UCS-2 er en 16-bit fastbreddekoding. Det betyr at bare en 16-biters kodeenhet brukes til å representere et kodepunkt. I teorien KAN UCS – 2 representere 21 i forskjellige tegn, men det er en vri.
💡 BTW, vi bruker begrepet kodeenhet i denne fastbreddekodingen for å forstå forholdet mellom UTF-16. I virkeligheten er det ikke noe slikt som kodeenhet i noen fast med koding.
siden UCS følger Unicode-tegnsettet, er kodingen av tegnene I UCS-2 identisk med kodingen av tegnene I UTF-16 som er representert i bare en kodeenhet.
💡 SIDEN UCS følger Unicode-tegnsettet, kan DET ikke kode et gyldig tegn med kodepunktene reservert for surrogatene.
så I nøtteskall inneholder UCS-2 tegnene Til Grunnleggende Flerspråklig Plan. Dette er grunnen, noen eldre dokumenter, og programvare som brukes UCS – 2 koding. Men UCS-2-koding har blitt foreldet og UTF-16 er foretrukket.
Endianness og BOM
SOM vi diskuterte før, INNEHOLDER EN utf-kodet dokumenter på lavt nivå sekvensen av kodeenheter. For utf-8 er kodeenheten 8 bits lang mens FOR UTF-16 er den 16 bits lang. Disse kodeenhetene utgjør tegnene.EN utf-8-eller utf-16-dekoder leser kodeenhetene sekvensielt, en kodeenhet om gangen for å generere tegnene.
hver kodeenhet representerer en numerisk verdi som en utf-8-eller utf-16-dekoder kan se på og avgjøre om det er tilstrekkelig å representere et tegn eller det følger andre kodeenheter som også bør vurderes.
når det gjelder UTF-8, er ting enkle. Siden hver kodeenhet er 8 biter lang, er det raskt og enkelt å konvertere det 8-biters binære tallet til en numerisk verdi. Dette er ikke tilfelle med UTF-16 skjont.
utf-16 kodeenhet er et 16-biters (2 byte) binært tall som representerer en kodepunktverdi. Å generere numerisk verdi fra flere byte er generelt vanskelig og forskjellige systemer oppfører seg annerledes.
denne oppførselen avhenger av systemets endianness. Fra vår tidligere diskusjon om endianness er det to måter vi kan skrive en utf-16 kodeenhetsverdi på. Enten I Big-endian format eller Lite-endian format.
I Big-endian format lagres MSB først og LSB lagres sist. Så langt skriver VI utf-16 kodeenhetsverdien I Big-endian-formatet. For å skrive utf-16 kode enhet verdi I Little-endian, må vi bytte byte.
La oss snakke om karakter आ. Fra tidligere eksempel, kan det være representert i bare en kode enhet AV UTF-16 og dens koding i heksadesimale representasjon ser ut som 0906itius.
0906itius er en 16-bit tall med 09 være MSB og 06 være LSB. Derfor i Big-endian arkitektur, vil den bli lagret som 09 06. Men I En Liten endisk arkitektur blir den lagret som 06 09.
derfor blir det vårt ansvar å kode tegn ved å ta hensyn til endianness av systemet slik at systemet kan lese et utf-16-dokument riktig.Men Hvordan kan vi vite på forhånd om en brukers maskin er kompatibel med det kodede dokumentet eller ikke? Og siden endianness av et system kan påvirke hvordan et dokument dekodes, hvordan deler vi det offentlig?
DET er her BOM kommer inn i bildet. BOM (BYTE Order Mark) er en byte sekvens som legges til i begynnelsen av en tekstfil eller tekstdata.Unicode anbefaler tegn med kodepunkt FEFFITIUS å fungere som EN BOM for UTF-16 og utf-32 kodinger. Dette tegnet bør før det første tegnet i dokumentet. Dette tegnet vil imidlertid ikke bli vurdert av dekoderen i utgangen.
dette tegnet (U + FEFF) er en null bredde non-breaking space (ZWNBSP) karakter og det er usynlig. Derfor, selv om en dekoder ikke gjenkjenner BOM, vil den ikke gi noen synlig utgang.
denne karakteren er representert i en enkelt kodeenhet AV UTF-16 og i heksadesimal representasjon ser DEN UT SOM FE (MSB) og FF (LSB).
Derfor når tegn er kodet I Big-endian-format, må vi legge TIL FEFF som BOM i begynnelsen av filen, og når tegn er kodet I Little-endian-format, må vi legge TIL FFFE (omvendt) som BOM i begynnelsen av filen.
Unicode anbefaler å legge BOM TIL utf-16 kodet dokument. Men hvis BOM mangler, antas Big-endian format.
iana foretrekker UTF – 16 som identifikator for å betegne et utf-16-kodet dokument. UTF-16be brukes imidlertid til dokument kodet I Big-endian-format, og UTF-16LE brukes Til Lite endian-format.
når utf-16be-eller utf-16LE-navn brukes, anbefales IKKE BOM å være forhåndsdefinert til en fil. Selv i dette tilfellet, hvis BOM er lagt til, så vil det bli vurdert SOM ZWNBSP karakter og det vil ikke bli ignorert.
💡 utf-16, utf-16be og utf-16LE navn er små bokstaver.
Fordeler og Ulemper
UTF-16 er effektiv fordi den bare har 2 kodeenheter, og siden de fleste brukte tegn faller i bmp-settet, kan de representeres i bare en kodeenhet. Det kommer imidlertid med mange problemer.Den største ulempen MED UTF-16 er at DEN ikke ER ASCII-kompatibel. SIDEN ASCII-tegn er kodet med en enkelt kodeenhet (16-biters tall), kan de ikke dekodes riktig av EN ASCII-dekoder.
UTF-16 bruker unødvendig plass FOR ASCII-tegn. Sammenlignet med utf-8-kodet dokument som bare inneholder ASCII-tegn, er størrelsen på det samme dokumentet kodet i UTF-16 to ganger større.
UTF-16 blir også påvirket av systemets endianness. Hvis STYKKLISTEN mangler og en passende kodingsidentifikator ikke brukes (som UTF-16LE), kan det hende at et utf-16-kodet dokument ikke blir dekodet riktig.
På grunn av UTF – 16-kodingens natur har den innført surrogatkodepunkter som ikke kan representere de gyldige tegnene. Dessuten har det begrenset Unicode tegnsett TIL 10FFFF ~ ~ POS = TRUNC (siste kodepunkt).
Til tross for disse fakta, noen av programmeringsspråk Som JavaScript, Java, etc. og systemer som Windows foretrekker utf-16-koding.