Was ist ein SMS-Zähler?
Ein SMS-Zähler ist ein Tool, das berechnet, wie viele Zeichen Ihre Nachricht enthält, den Kodierungstyp (GSM 7-Bit oder UCS-2) erkennt und bestimmt, in wie viele SMS-Segmente die Nachricht aufgeteilt wird. Dies ist wichtig, weil Mobilfunkanbieter pro Segment und nicht pro Nachricht abrechnen und das Überschreiten des Einzel-SMS-Limits Ihre Kosten ohne Vorwarnung verdoppeln oder verdreifachen kann.
Im Gegensatz zu einem normalen Zeichenzähler berücksichtigt ein SMS-Zähler die technischen Einschränkungen des Short Message Service-Standards, der in GSM 03.38 definiert ist. Er berücksichtigt nicht nur die Länge Ihres Textes, sondern auch, welche Zeichen er enthält und wie sie für die Übertragung über Mobilfunknetze kodiert werden müssen.
Wie GSM-7-Bit-Kodierung funktioniert
Die GSM-03.38-Spezifikation definiert ein Standardalphabet von 128 Zeichen, die mit jeweils 7 Bit kodiert werden können. Dies umfasst Groß- und Kleinbuchstaben des lateinischen Alphabets, Ziffern, gebräuchliche Satzzeichen und einige spezielle Symbole. Da jedes Zeichen nur 7 Bit anstelle von 8 Bit verwendet, passt eine einzelne SMS bis zu 160 Zeichen — berechnet als (140 Bytes × 8 Bits) / 7 Bits pro Zeichen.
GSM-7-Bit-Basiszeichensatz:
| Kategorie | Zeichen |
|---|---|
| Buchstaben | A–Z, a–z |
| Ziffern | 0–9 |
| Satzzeichen | @, !, ", #, $, %, &, ', (, ), *, +, ,, -, ., / |
| Symbole | :, ;, <, =, >, ?, ¡, ¿, ¤, £, ¥, §, ¨, ©, ®, ´, `, ^, ~, ¯ |
| Speziell | Leerzeichen, Zeilenumbruch, Wagenrücklauf |
| Erweitert | ^, {, }, , [, ~, ], , € (erfordern Escape-Byte) |
Erweiterte GSM-7-Bit-Zeichen — wie ^, {, }, [, ], ~, | und € — erfordern einen Escape-Code (0x1B) vor dem Zeichen. Dieses Escape-Byte verbraucht Platz in der Nachricht, sodass jedes erweiterte Zeichen effektiv als 2 Zeichen in Richtung des 160-Zeichen-Limits zählt.
UCS-2-Kodierung: Wenn 7 Bit nicht ausreichen
Wenn Ihre Nachricht Zeichen außerhalb des GSM-7-Bit-Alphabets enthält — wie Emojis, geschweifte Anführungszeichen, akzentuierte Buchstaben wie é oder ü, Gedankenstriche wie — oder andere Unicode-Symbole — wechselt die gesamte Nachricht zur UCS-2-Kodierung (16 Bit). Im UCS-2-Modus belegt jedes Zeichen 16 Bit, wodurch sich die Einzel-SMS-Kapazität von 160 auf 70 Zeichen reduziert.
Zeichen, die UCS-2-Kodierung erzwingen:
- Emojis und Piktogramme (
😊,🚀,❤️) - Geschweifte Anführungszeichen (
"",'') - Lange Gedankenstriche (
—,–) - Akzentuierte Zeichen, die nicht im GSM-Basissatz enthalten sind (
ě,ř,č) - Währungssymbole über
$,£,¥,€hinaus - Pfeile (
→,←,↑,↓) - Mathematische Symbole (
∑,∫,√,∞) - Die meisten CJK-Zeichen (Chinesisch, Japanisch, Koreanisch)
Sobald eine Nachricht auch nur ein einziges UCS-2-Zeichen enthält, verwendet die gesamte Nachricht 16-Bit-Kodierung. Es gibt keinen Hybridmodus — entweder alles 7-Bit oder alles 16-Bit.
Mehrteilige SMS und Segmentgrenzen
Wenn Ihre Nachricht das Einzel-SMS-Limit überschreitet (160 GSM-Zeichen oder 70 UCS-2-Zeichen), teilt der Betreiber sie in mehrere Segmente auf. Jedes Segment enthält einen 6-Byte-User-Data-Header (UDH) für den Zusammenbau, der den verfügbaren Nutzdatenplatz reduziert.
| Kodierung | Einzel-SMS | Mehrteilig (pro Segment) |
|---|---|---|
| GSM 7-Bit | 160 Zeichen | 153 Zeichen |
| UCS-2 | 70 Zeichen | 67 Zeichen |
Wie die Berechnung funktioniert:
GSM 7-Bit mehrteilig:
zeichen_pro_segment = (140 - 6) × 8 / 7 = 153
UCS-2 mehrteilig:
zeichen_pro_segment = (140 - 6) / 2 = 67
Eine 200-Zeichen-Nachricht in GSM-7-Bit-Kodierung wird in 2 Segmente aufgeteilt (153 + 47). Eine 150-Zeichen-Nachricht mit Emojis wird in 3 UCS-2-Segmente aufgeteilt (67 + 67 + 16). Die meisten Betreiber berechnen pro Segment, daher hilft das Verständnis dieser Grenzen, die Kosten zu kontrollieren.
Code-Beispiele
PHP: SMS-Segmente zählen
function countSmsSegments(string $text): array {
$gsm7 = '@£$¥èéùìòÇØøÅåΔ_ΦΓΛΩΠΨΣΘΞÆæßÉ !"#¤%&\'()*+,-./0123456789:;<=>?¡ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÑܧ¿abcdefghijklmnopqrstuvwxyzäöñüà';
$gsm7ext = ['^', '{', '}', '\\', '[', '~', ']', '|', '€'];
$isUcs2 = false;
$extCount = 0;
for ($i = 0; $i < mb_strlen($text); $i++) {
$char = mb_substr($text, $i, 1);
if (in_array($char, $gsm7ext)) {
$extCount++;
} elseif (mb_strpos($gsm7, $char) === false) {
$isUcs2 = true;
break;
}
}
if ($isUcs2) {
$maxPerSegment = 70;
$segments = (int)ceil(mb_strlen($text) / $maxPerSegment);
// Mehrteilig reduziert das Limit
if ($segments > 1) {
$maxPerSegment = 67;
$segments = (int)ceil(mb_strlen($text) / $maxPerSegment);
}
return ['encoding' => 'UCS-2', 'segments' => $segments, 'chars_per_segment' => $maxPerSegment];
}
$effectiveLength = mb_strlen($text) + $extCount;
$maxPerSegment = 160;
$segments = (int)ceil($effectiveLength / $maxPerSegment);
if ($segments > 1) {
$maxPerSegment = 153;
$segments = (int)ceil($effectiveLength / $maxPerSegment);
}
return ['encoding' => 'GSM 7-bit', 'segments' => $segments, 'chars_per_segment' => $maxPerSegment];
}
JavaScript: SMS-Kodierung erkennen
const GSM7_BASIC = new Set(
'@£$¥èéùìòÇØøÅåΔ_ΦΓΛΩΠΨΣΘΞÆæßÉ !"#¤%&\'()*+,-./0123456789:;<=>?¡' +
'ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÑܧ¿abcdefghijklmnopqrstuvwxyzäöñüà'.split('')
);
const GSM7_EXT = new Set(['^', '{', '}', '\\', '[', '~', ']', '|', '€']);
function detectSmsEncoding(text) {
let extCount = 0;
for (const char of text) {
if (GSM7_EXT.has(char)) {
extCount++;
} else if (!GSM7_BASIC.has(char)) {
return { encoding: 'UCS-2', extCount: 0 };
}
}
return { encoding: 'GSM 7-bit', extCount };
}
const result = detectSmsEncoding('Hello World! €50');
console.log(result); // { encoding: 'GSM 7-bit', extCount: 1 }
Python: SMS-Teile berechnen
def sms_parts(text: str) -> dict:
gsm7_basic = set('@£$¥èéùìòÇØøÅåΔ_ΦΓΛΩΠΨΣΘΞÆæßÉ !"#¤%&\'()*+,-./0123456789:;<=>?¡ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÑܧ¿abcdefghijklmnopqrstuvwxyzäöñüà')
gsm7_ext = {'^', '{', '}', '\\', '[', '~', ']', '|', '€'}
is_ucs2 = False
ext_count = 0
for char in text:
if char in gsm7_ext:
ext_count += 1
elif char not in gsm7_basic:
is_ucs2 = True
break
if is_ucs2:
limit = 70 if len(text) <= 70 else 67
parts = (len(text) + limit - 1) // limit
return {'encoding': 'UCS-2', 'parts': parts, 'chars_per_part': limit}
effective = len(text) + ext_count
limit = 160 if effective <= 160 else 153
parts = (effective + limit - 1) // limit
return {'encoding': 'GSM 7-bit', 'parts': parts, 'chars_per_part': limit}
print(sms_parts('Hello World')) # 1 part, GSM 7-bit
print(sms_parts('Hello 😊 World')) # UCS-2 encoding triggered
Warum SMS-Kodierung für Entwickler wichtig ist
Wenn Sie Anwendungen entwickeln, die SMS-Benachrichtigungen senden — wie Zwei-Faktor-Authentifizierungscodes, Terminerinnerungen oder Marketingkampagnen — hilft Ihnen das Verständnis der SMS-Kodierung, sowohl die Zustellbarkeit als auch die Kosten zu kontrollieren.
Wichtige Erkenntnisse für Entwickler:
- Validieren Sie immer die Nachrichtenlänge vor dem Senden, um unerwartete Mehrteile-Gebühren zu vermeiden
- Entfernen oder ersetzen Sie UCS-2-Zeichen nach Möglichkeit, um Nachrichten in GSM 7-Bit zu halten
- Testen Sie mit erweiterten Zeichen wie
€und[]— sie komprimieren sich anders als einfache GSM-Zeichen - Berücksichtigen Sie den 6-Byte-UDH-Overhead bei der Schätzung der Mehrteile-Kapazität
- Ziehen Sie die Verwendung eines speziellen SMS-Zähler-Tools während der Entwicklung und des Testens in Betracht
Online-Tool
Der SMS Counter auf Help2Code bietet Echtzeit-Zeichenzählung, Kodierungserkennung und Segmentvorschau. Fügen Sie Ihre Nachricht ein und sehen Sie sofort, ob sie GSM-7-Bit- oder UCS-2-Kodierung verwendet, wie viele Segmente erforderlich sind und wo genau jeder Segmentbruch erfolgt. Die farbcodierte Kodierungsvorschau zeigt Ihnen, welche Zeichen den Unicode-Modus auslösen und welche im 7-Bit-Modus sicher sind.
Fazit
Ein SMS-Zähler ist ein unverzichtbares Werkzeug für jeden, der Textnachrichten programmatisch versendet oder unerwartete Gebühren vermeiden möchte. Durch das Verständnis des Unterschieds zwischen GSM-7-Bit- und UCS-2-Kodierung und der Funktionsweise der Mehrteile-Segmentierung können Sie kosteneffizientere SMS-Anwendungen schreiben und Zustellungsprobleme schneller beheben. Verwenden Sie den SMS Counter, um Ihre Nachrichten zu testen, bevor Sie sie in der Produktion versenden.