GSM-7 vs UCS-2: waarom één emoji je SMS-rekening verdubbelt
Eén emoji kan stilletjes een SMS-rekening verdubbelen of verdrievoudigen. GSM 03.38 definieert twee encodings voor de 140-byte payload: compact GSM-7 met 160 tekens, of UCS-2 met 70. Elk teken buiten het GSM-7-alfabet dwingt het hele bericht naar UCS-2. Developers en marketeers die tekst plakken uit tekstverwerkers merken dit vaak pas als de facturen binnenkomen.
GSM-7-packing: 160 tekens in een 140-byte payload
SMS is ontworpen rond een vaste user-data-payload van 140 bytes. GSM 03.38 definieert een 7-bits standaardalfabet zodat die 140 bytes 160 septetten kunnen bevatten: 140 keer 8 gedeeld door 7 is 160. Blijft een bericht volledig binnen dat alfabet, dan behandelen handset en SMSC het als één segment van maximaal 160 tekens. De basistabel dekt hoofd- en kleine Latijnse letters, cijfers, gangbare leestekens en enkele valuta- en nationale symbolen. Spaties, regeleinden en gewone Engelse prozatekens passen zonder extra kosten.
Concatenatie verandert de rekensom. Meerdelige berichten voegen een User Data Header in zodat het ontvangende apparaat segmenten in volgorde kan samenvoegen. Een typische UDH van 6 bytes verbruikt septet-ruimte, waardoor 153 tekens bruikbare tekst per segment overblijven onder GSM-7. Facturatie gebeurt vrijwel altijd per segment, niet per logisch bericht, dus een GSM-7-body van 200 tekens wordt twee factureerbare segmenten (153 plus het restant). Het 160-versus-153-verschil begrijpen is de eerste stap om kosten te voorspellen vóór je op verzenden drukt.
De extensietabel: tekens die al twee septetten kosten
GSM 03.38 definieert ook een uitbreidingstabel die via een apart escape-septet wordt bereikt. Tekens zoals de vierkante haken [ ], accolades { }, het dakje ^, de tilde ~, de verticale streep |, de backslash \ en het euroteken horen niet tot de basistabel. Elk daarvan wordt gecodeerd als escape plus het uitbreidingscodepunt, zodat elk twee van de 160 (of 153) beschikbare septetten verbruikt. Een bericht dat er op het scherm kort uitziet, kan daardoor eerder een segmentgrens overschrijden dan een naïeve tekentelling suggereert.
Het escape-mechanisme blijft GSM-7; het zet het bericht niet om naar UCS-2. Dat onderscheid telt. Je kunt een paar eurotekens of haakjes opnemen en in de efficiënte 7-bits packing blijven. Pas wanneer de encoder een codepoint tegenkomt dat in noch het basisalfabet noch de extensietabel zit, verlaat het hele bericht GSM-7. Tot dat moment telt elk teken - inclusief de dubbel kostende extensietekens - nog in septetten tegen de limiet van 160 of 153.
| Tekenklasse | Septetten verbruikt onder GSM-7 |
|---|---|
| Basisalfabet (A–Z, a–z, 0–9, gangbare leestekens) | 1 |
| Extension table ([ ] { } ^ ~ | \ and euro) | 2 (escape + code) |
| Alles buiten GSM 03.38 (emoji, krullende aanhalingstekens, meeste niet-Latijnse) | Dwingt hele bericht naar UCS-2 |
UCS-2-fallback: één teken buiten het alfabet hercodeert alles
Zodra een teken niet in GSM-7 weer te geven is, schakelt de encoder de volledige user data over naar 16-bits UCS-2 (effectief UTF-16-code-units voor de BMP). Dezelfde 140-byte payload houdt dan slechts 70 tekens. Met een concatenatie-UDH daalt de bruikbare lengte naar 67 tekens per segment. Er is geen gedeeltelijke fallback: één emoji, een slim aanhalingsteken, een en-streepje of een teken uit Arabisch, Cyrillisch, CJK of de meeste andere schriften herschrijft de hele body. Een Engelse zin van 140 tekens die één GSM-7-segment was, wordt drie UCS-2-segmenten zodra er een lachend gezichtje achter komt.
Dit is het mechanisme achter de verrassingsfactuur. Marketeers schrijven vaak tekst in een tekstverwerker, plakken die in een SMS-tool en introduceren ongemerkt krullende aanhalingstekens of een harde spatie. Developers die door gebruikers gegenereerde namen of producttitels interpoleren kunnen dezelfde onzichtbare trigger injecteren. Omdat de hercodering alles-of-niets is, springt het segmentaantal sprongsgewijs omhoog. Facturatie vermenigvuldigt met het nieuwe segmenttotaal. Gepubliceerde all-in bedragen zoals US $0,0125 per bericht, met tarieven vanaf $0,004 in 149 landen, maken de rekensom concreet: elk extra segment is opnieuw een volledige kost, geen fractionele toeslag.
| Encoding | Limiet enkel segment | Limiet geconcateneerd segment |
|---|---|---|
| GSM-7 (7-bit) | 160 tekens | 153 tekens |
| UCS-2 (16-bit) | 70 tekens | 67 tekens |
Onzichtbare valkuilen en schriften die UCS-2 forceren
Tekstverwerkers vervangen routinematig rechte apostrofs en aanhalingstekens door krullende typografische vormen, zetten dubbele koppeltekens om in em-streepjes en voegen non-breaking spaces in. Geen van die codepoints hoort bij GSM 03.38. Een bericht dat op scherm identiek lijkt aan een plain-ASCII-versie kan daardoor als UCS-2 reizen en meerdere segmenten kosten. Hetzelfde geldt voor gekopieerde content van webpagina's of designtools die rijker Unicode prefereren. De werkelijke codepoints controleren, niet de gerenderde glyphs, is de enige betrouwbare verdediging.
Taalkeuze is even beslissend. Puur Engels, basis-Frans, -Duits, -Spaans en vergelijkbare Latijnse berichten blijven meestal in GSM-7 als accentletters buiten het standaardalfabet worden vermeden of getranslitereerd. Grieks, Cyrillisch, Arabisch, Hebreeuws, Devanagari, Thai en de CJK-familie hebben geen GSM-7-mapping voor gewone letters, dus elk substantieel gebruik van die schriften forceert UCS-2 voor het hele bericht. Zelfs één naam of productwoord in die schriften volstaat. Emoji van elke soort vallen per definitie buiten GSM-7. De praktische regel is eenvoudig: zit het teken niet in de GSM 03.38-basis- of extensieset, dan wordt de hele payload 70/67.
Praktische fixes vóór je verzendt
Transliteratie houdt berichten in GSM-7 ten koste van orthografische trouw. Accenttekens vervangen door dichtstbijzijnde ASCII-equivalenten, krullende aanhalingstekens omzetten naar rechte en em-streepjes terugmappen naar koppeltekens herstelt vaak de 160/153-limieten. Voor merknamen of juridische tekst die exact moet blijven, accepteer UCS-2 en budgetteer het hogere segmentaantal. Geautomatiseerde pre-flight checks die scannen op non-GSM-7-codepoints en het resulterende segmenttotaal onder beide encodings rapporteren geven developers en marketeers een duidelijk kostensignaal vóór het bericht naar de SMSC gaat.
Bij het bouwen van templates houd variabele velden scherp in de gaten: een klantnaam in een ander schrift of een producttitel met emoji kan een verder GSM-7-template stil omzetten. Strip of normaliseer plakbuffers uit rich-text-bronnen. Gebruik bij voorkeur rechte ASCII-leestekens in marketingcopy voor SMS. Moet je emoji of niet-Latijnse tekst sturen, ontwerp de body dan zo dat de UCS-2-segmentgrenzen op natuurlijke zinsdelen vallen en houd de totale lengte binnen zo weinig mogelijk stukken van 67 tekens. Segmentbewuste lengtetellers die wisselen tussen 160/153 en 70/67 op basis van het gedetecteerde alfabet nemen de meeste verrassing weg. Tarieven verschillen per carrier en route; de eerder genoemde cijfers illustreren het per-segmentmodel, geen universeel tarief. Eerlijke onzekerheid blijft bestaan over exacte handsetweergave van randtekens, dus test op representatieve apparaten wanneer het bericht ertoe doet.
Veelgestelde vragen
- Waarom verandert één emoji mijn SMS in meerdere berichten?
- Elk teken buiten het GSM 03.38-alfabet, inclusief elke emoji, dwingt het hele bericht van GSM-7 naar UCS-2. De 140-byte payload bevat dan 70 tekens in plaats van 160 (67 in plaats van 153 bij aaneenschakeling). Een body die in één GSM-7-segment paste, kan daardoor twee of drie UCS-2-segmenten worden, en facturering gebeurt per segment.
- Veranderen gekrulde aanhalingstekens en gedachtestreepjes echt de SMS-codering?
- Ja. Typografische gekrulde aanhalingstekens, gedachtestreepjes, en-streepjes en harde spaties zitten niet in de GSM-7 basis- of extensiesets. Plakken vanuit een tekstverwerker hercodeert het hele bericht als UCS-2, waardoor de limiet per segment daalt van 160/153 naar 70/67, zelfs als de tekst er op het scherm onveranderd uitziet.
- Hoeveel tekens passen in een aaneengeschakelde SMS onder GSM-7 versus UCS-2?
- Onder GSM-7 bevat een aaneengeschakeld segment 153 tekens na de typische 6-byte UDH. Onder UCS-2 laat dezelfde header 67 tekens per segment over. Limieten voor enkelvoudige segmenten zijn 160 voor GSM-7 en 70 voor UCS-2. Het aantal segmenten, niet het logische berichtenaantal, bepaalt de kosten.