Unicode
standarden som ger varje tecken ett eget nummer

Foto: Iguanat / Pixabay 
Foto: WOKANDAPIX / Pixabay
Använd begreppet i ett beslut
Använd ”Vad är Unicode?” i ett konkret beslut. Vi kan knyta begreppet till systemet du bygger eller köper. Mjukvara som känns naturlig på varje marknad du säljer på, inklusive datum, valutor och hur namn sorteras.
Granska antagandena bakom ordet
Använd förklaringen och det länkade arbetet för att formulera frågor till projektet. Vi kan undersöka antagandena tillsammans innan ett verktyg väljs. Byggde ett i18n‑system för engelska och danska — 12,027 meddelanden per språkversion, på engelska och danska
Vad det är
Unicode är standarden som ger varje bokstav, siffra, skiljetecken och symbol i världens skriftsystem ett eget nummer. Enligt dem som underhåller standarden är Unicode den universella teckenkodningen: utformad för att text på den moderna världens språk och inom dess tekniska fält ska kunna utbytas, bearbetas och visas var som helst, och utökad till klassiska och historiska texter på många skriftspråk. En och samma repertoar rymmer det svenska å, det ukrainska Ґ, eurotecknet och bokstäverna i skrifter som ingen har skrivit på i århundraden, så att ett enda dokument, eller en enda kolumn i en databas, kan innehålla dem alla.
Formellt består en version av Unicode-standarden av kärnspecifikationen, kodtabellerna, standardens bilagor, Unicode Standard Annexes, och Unicode Character Database, de maskinläsbara filer som beskriver varje teckens egenskaper. Unicode Technical Committee underhåller standarden löpande, Unicode-konsortiet ger ut den, och version 18.0 tillkännagavs den 16 september 2026.
Numret som ett tecken får kallas dess kodpunkt. Kodrymden går från 0 till 10FFFF hexadecimalt, 1 114 112 kodpunkter totalt, och en kodpunkt skrivs som U+ följt av minst fyra hexadecimala siffror: å är U+00E5, Ґ är U+0490 och eurotecknet är U+20AC. Konsortiets stabilitetsregler lovar att ett tecken aldrig flyttas eller tas bort när det väl har kodats, och att dess namn aldrig ändras, så text som kodas i dag betyder samma sak i alla senare versioner.
Två distinktioner bär det mesta av standarden. Den första går mellan tecken och glyf. Unicode kodar tecknet, den abstrakta bokstaven, och överlåter formen åt typsnittet: kärnspecifikationen slår fast att glyfernas utseende är typsnittsleverantörernas ansvar och inte en del av standarden. Samma kodpunkt kan se olika ut i två typsnitt, och ett typsnitt som saknar en form för den kan inte rita den alls. Den andra går mellan kodpunkten och de byte som lagrar den. Unicode definierar tre kodningsformer, UTF-8, UTF-16 och UTF-32, som skriver varje kodpunkt som en eller flera enheter om 8, 16 eller 32 bitar, och specifikationen kallar det en fälla att göra det till en fråga om ”UTF-8 versus Unicode”: alla tre är lika giltiga sätt att implementera samma tecken.
Varför det spelar roll
Före Unicode hade varje skrift sina egna kodsidor, och en byte betydde ingenting förrän man visste vilken sida som användes. I den västeuropeiska kodsidan windows-1252 är byten E5 ett å; i den kyrilliska windows-1251 är samma byte bokstaven е. Ingen av sidorna kunde rymma den andras bokstäver: windows-1251 har Ґ men varken å, ä eller ö, och i windows-1252 är det tvärtom. En produkt på svenska och ukrainska behövde två kodningar och god ordning på vilken text som använde vilken, och en mening som citerade båda språken gick inte att lagra alls.
Unicode gjorde den bokföringen överflödig. Alla språk som en produkt ges ut på, och alla namn som en kund skriver i ett formulär, ryms i en och samma teckenuppsättning, och samma nummer betyder samma tecken i alla system som läser det. Det är det som låter en databas, ett API och en webbläsare skicka text mellan sig utan att först komma överens om en kodsida.
Standarden avgör också frågor som annars skulle avgöras olika i varje program. Den slår ihop tecken över språkgränser: kommat är ett och samma tecken oavsett om det skiljer tusental åt, som på engelska, eller decimaler, som på svenska, så det är språket och dess konventioner, inte kodpunkten, som avgör betydelsen. Den slår inte ihop tecken över skriftgränser: det latinska o, det kyrilliska о och det grekiska ο ser likadana ut i de flesta typsnitt och är tre tecken, eftersom de hör till tre skrifter och äldre kodningar redan höll isär dem. Och den slår fast vilka sekvenser som är ekvivalenta. Å kan lagras som ett färdigt sammansatt tecken eller som A följt av en kombinerande ring, och standarden definierar de två som kanoniskt ekvivalenta, så att de ska visas och tolkas likadant, med normaliseringsformer som för över båda till en överenskommen stavning.
Den bredden har ett pris, och det är programmeraren som betalar det. Ett tecken är inte en byte, inte alltid en enhet i en sträng och inte alltid det som en läsare räknar som en bokstav. Kod som behandlar de tre som samma sak klarar sina tester med engelska data och fallerar på namnen, adresserna och meddelandena från just de människor den skrevs för.
Så ser det ut i praktiken
JavaScript gör lagren synliga. En sträng är en följd av UTF-16-kodenheter, och sprider man ut den i en array delas den upp i kodpunkter:
const hex = (n) => n.toString(16).toUpperCase().padStart(4, "0");
for (const text of ["a", "å", "Ґ", "€", "𐌂"]) {
const points = [...text].map((c) => "U+" + hex(c.codePointAt(0)));
console.log(text, points.join(" "), text.length, [...text].length);
}Kört i Node.js 25 skriver koden ut varje tecken, dess kodpunkt, dess längd i UTF-16-enheter och dess längd i kodpunkter:
a U+0061 1 1
å U+00E5 1 1
Ґ U+0490 1 1
€ U+20AC 1 1
𐌂 U+10302 2 1Den sista raden är en fornitalisk bokstav. Dess kodpunkt ligger över U+FFFF, så
UTF-16 lagrar den som två enheter, ett surrogatpar, och length rapporterar 2
för det som är ett tecken.
Ekvivalens syns på samma sätt. Här är tre strängar som alla visas som Å:
const forms = ["\u00C5", "A\u030A", "\u212B"];
console.log("form length equal NFC");
for (const [i, s] of forms.entries()) {
console.log(i + 1, s.length, s === forms[0], s.normalize("NFC") === forms[0]);
}form length equal NFC
1 1 true true
2 2 false true
3 1 false trueDen första är den färdigt sammansatta bokstaven, U+00C5. Den andra är ett vanligt A följt av U+030A, den kombinerande ringen ovanför. Den tredje är U+212B, ångströmtecknet, som Unicode Character Database för tillbaka till U+00C5. Jämförda som de är, är de tre olika strängar; efter normalisering till NFC är alla tre samma sträng. Ingenting på skärmen skiljer dem åt, så en sökning, ett unikt index eller en inloggning som jämför de råa strängarna ser tre olika namn.
Även den här webbplatsen är beroende av kodpunkter, bara på ett mindre synligt ställe. Anteckningen om understrykningen som korsade varje bokstav beskriver hur webbplatsen serverar sitt typsnitt i sex delar, tre vikter med latinska tecken och tre med kyrilliska, så att en ukrainsk sida sätts i samma typsnitt som en engelsk. Varje del deklarerar det teckenintervall den täcker, och webbläsaren laddar bara ned de delar som en sida faktiskt behöver. Den kyrilliska deklarationen anger sitt intervall i kodpunkter:
unicode-range: U+0400-045F, U+0490-0491;Det första intervallet går från Ѐ till џ och rymmer de ukrainska Є, І och Ї tillsammans med resten av det grundläggande kyrilliska alfabetet. Det andra rymmer bara Ґ och ґ, som ligger längre fram i det kyrilliska blocket. Teckenintervallen avgör vad som laddas ned, och anteckningen konstaterar resultatet: engelska och danska sidor hämtar tre latinska filer och inga kyrilliska.
Var det går fel
Längden räknas i kodenheter. JavaScripts length räknar UTF-16-enheter, så
𐌂 räknas som två, och ett A med kombinerande ring räknas som två där en läsare
ser en bokstav. En gräns som upprätthålls i enheter avvisar text som får plats,
och ett snitt vid en fast position kan dela ett tecken: "A\u030A".slice(0, 1)
behåller A:et och tappar ringen, och delar man 𐌂 på mitten blir ett ensamt
surrogat kvar, som UTF-8-kodaren ersätter med U+FFFD, ersättningstecknet. Bestäm
för varje gräns vad den räknar: byte där det är lagringen som sätter gränsen,
och tecken så som läsaren ser dem där det är en människa som gör det.
Intl.Segmenter räknar på det senare sättet, och för Umeå skrivet med
kombinerande ring ger den 4 där length ger 5. Klipp bara text vid de gränser
den rapporterar.
Likadan text jämförs enhet för enhet. De tre formerna av Å ovan är tre olika
strängar för ===, för en hashfunktion och för ett unikt index, så en kund kan
registrera samma namn två gånger eller inte hitta ett dokument utifrån den titel
kunden skrev. Normalisera text till NFC där den kommer in i systemet, lagra den
normaliserad och jämför normaliserade former. Stabilitetsreglerna garanterar att
en sträng som är normaliserad under en version förblir normaliserad under alla
senare, förutsatt att strängen bara innehåller tecken som den versionen känner
till, så koden som normaliserar måste vara lika ny som texten.
Tecken som ser likadana ut tas för samma tecken. Det latinska o, det kyrilliska о och det grekiska ο är olika kodpunkter som de flesta typsnitt ritar likadant, så två kontonamn eller två artikelnummer kan se identiska ut och skilja sig i ett enda tecken. Unicode håller medvetet isär dem, och konsortiets standard för säkerhetsmekanismer, UTS #39, beskriver hur den sortens förfalskning kan begränsas. Där ett namn identifierar en person eller en betalningsmottagare bör du bara tillåta en skrift per namn eller kontrollera namnet mot standardens säkerhetsdata innan det godkänns.
Byte läses med fel kodning. Text som har lagrats som UTF-8 och läses som windows-1252 förvandlar blåbär till blÃ¥bär, eftersom varje bokstav på två byte läses som två bokstäver på en byte var. Ordet Unicode säger inte hur texten skrevs som byte; det gör bara kodningsformen. Ange den överallt där text korsar en gräns, i HTTP-headern, på sidan, på databasanslutningen och i filformatet, och behandla en fil som kommer utan som en fråga till en människa och inte som en gissning åt koden.
Texten får skulden för en saknad glyf. När en bokstav visas som en tom ruta är orsaken oftast ett typsnitt som saknar en form för den kodpunkten, och själva texten är intakt. Eftersom Unicode överlåter formerna åt typsnitten måste varje typsnitt som en produkt använder täcka alla tecken som dess språk behöver, de ukrainska Є, І, Ї och Ґ lika väl som А till я, annars ritar webbläsaren dem med det reservtypsnitt den hittar. Anteckningen ovan anger just det som skälet till att webbplatsen alls serverar kyrilliska delar: utan dem skulle en ukrainsk sida falla tillbaka på vad systemet nu erbjuder. Testa varje språk med hela dess alfabet i stället för en enstaka exempelmening.
Namn kontrolleras mot A till Z. Ett mönster som ^[A-Za-z' -]+$ godkänner
O’Neill och avvisar Åsa Lindström, Zoë och Ґалаґан, alltså just de namn som en
svensk eller ukrainsk produkt finns till för. Avgör i stället om ett tecken är
en bokstav utifrån dess Unicode-egenskaper: i JavaScript godkänner
/^[\p{L}\p{M}' -]+$/u alla fyra. Egenskaperna kommer från den kopia av Unicode
Character Database som finns i körmiljön, och Node.js 25 har version 16.0, så
bokstäver som har tillkommit i senare versioner avvisas tills körmiljön
uppgraderas. Validera namn generöst och låt en människa, inte ett mönster,
avgöra de svåra fallen.
Läs mer
- About the Unicode Standard — konsortiets egen beskrivning av standarden, vad en version består av och var den senaste publiceras.
- The Unicode Standard, Chapter 2: General Structure — de tio designprinciperna, kodrymden, de tre kodningsformerna och reglerna för ekvivalenta sekvenser.
- Unicode Character Encoding Stability Policies — det som aldrig kan ändras när ett tecken väl har kodats, från kodpunkten och namnet till normaliseringen.
- Unicode 18.0.0 — vad den aktuella versionen tillför och de tekniska standarder som versioneras tillsammans med den, bland dem sortering och säkerhet.

