GSM-7 is the default character set for SMS. Its formal name is the GSM 7 bit default alphabet, and it is defined in the standard 3GPP TS 23.038. It has 128 code positions, each stored in 7 bits, which is how the 140 bytes of a text message hold 160 characters. The set covers the unaccented Latin alphabet, the digits, common punctuation, a small group of accented letters and ten Greek capitals. A message written only with these characters gets the 160 limit. One character from outside the set and the whole message is sent as Unicode, with a limit of 70.
Older documents and some provider pages call it GSM 03.38, after the earlier ETSI specification that defined it.
Why seven bits
A short message has 140 octets (bytes) for its text. Storing each character in 7 bits instead of 8 fits more of them into the same space, and the standard does the sum itself: "in 140 octets, it is possible to pack (140x8)/7=160 characters". The characters are packed end to end, so eight of them occupy seven bytes.
Seven bits give 2⁷ = 128 possible values, and that fixes the size of the alphabet. The standard requires every phone and network to support it: "Implementation of the GSM 7 bit default alphabet is mandatory. Support of other character sets is optional."
The basic character set
To find a character's code, add the row label to the column heading. A is in column 0x40, row 1, so its code is 0x41.
| + | 0x00 | 0x10 | 0x20 | 0x30 | 0x40 | 0x50 | 0x60 | 0x70 |
|---|---|---|---|---|---|---|---|---|
| 0 | @ |
Δ |
SP | 0 |
¡ |
P |
¿ |
p |
| 1 | £ |
_ |
! |
1 |
A |
Q |
a |
q |
| 2 | $ |
Φ |
" |
2 |
B |
R |
b |
r |
| 3 | ¥ |
Γ |
# |
3 |
C |
S |
c |
s |
| 4 | è |
Λ |
¤ |
4 |
D |
T |
d |
t |
| 5 | é |
Ω |
% |
5 |
E |
U |
e |
u |
| 6 | ù |
Π |
& |
6 |
F |
V |
f |
v |
| 7 | ì |
Ψ |
' |
7 |
G |
W |
g |
w |
| 8 | ò |
Σ |
( |
8 |
H |
X |
h |
x |
| 9 | Ç |
Θ |
) |
9 |
I |
Y |
i |
y |
| A | LF | Ξ |
* |
: |
J |
Z |
j |
z |
| B | Ø |
ESC | + |
; |
K |
Ä |
k |
ä |
| C | ø |
Æ |
, |
< |
L |
Ö |
l |
ö |
| D | CR | æ |
- |
= |
M |
Ñ |
m |
ñ |
| E | Å |
ß |
. |
> |
N |
Ü |
n |
ü |
| F | å |
É |
/ |
? |
O |
§ |
o |
à |
SP is the space, LF the line feed and CR the carriage return. ESC, at 0x1B, is not a character: it announces that the next code comes from the extension table.
That leaves 127 characters:
- 52 unaccented letters,
AtoZandatoz, and the 10 digits - 23 further Latin letters:
è é ù ì ò Ç Ø ø Å å Æ æ ß É Ä Ö Ñ Ü ä ö ñ ü à - 10 Greek capitals:
Δ Φ Γ Λ Ω Π Ψ Σ Θ Ξ - 29 punctuation marks and symbols, among them
£,¥,¤,§,¡and¿ - the space, the line feed and the carriage return
Each uses one of the 160 units, a line break included.
It looks like ASCII, but it is not
GSM-7 is the same size as ASCII, and the unaccented letters and digits sit at the same codes. Much of the rest has moved:
@is at 0x00. ASCII has it at 0x40, where GSM-7 has¡.$is at 0x02. Its ASCII position, 0x24, holds the currency sign¤._is at 0x11. Its ASCII position, 0x5F, holds§.- The ASCII position of the backtick, 0x60, holds
¿. - The ASCII positions of
[ \ ] ^holdÄ Ö Ñ Ü, and those of{ | } ~holdä ö ñ ü.
Software that treats GSM-7 codes as ASCII, or the reverse, gets these characters wrong.
The extension table
Ten more characters are reachable through the escape code. Each is sent as 0x1B followed by a second code, so each uses two units instead of one.
| Character | Sent as | Unicode |
|---|---|---|
^ |
0x1B 0x14 | U+005E |
{ |
0x1B 0x28 | U+007B |
} |
0x1B 0x29 | U+007D |
\ |
0x1B 0x2F | U+005C |
[ |
0x1B 0x3C | U+005B |
~ |
0x1B 0x3D | U+007E |
] |
0x1B 0x3E | U+005D |
| |
0x1B 0x40 | U+007C |
€ |
0x1B 0x65 | U+20AC |
| form feed (page break) | 0x1B 0x0A | U+000C |
The cost of these characters, and an awkward rule about where they may fall in a split message, is covered in why some SMS characters count twice.
What is missing
Some absences catch people out:
- The backtick and the tab. Neither is in the basic table or the extension table.
- Lower-case
ç. The capitalÇis there; the small letter is not (more on this below). - Most accented vowels.
á,í,ó,ú,â,ê,î,ô,û,ã,õ,ëandïare all absent. So are most accented capitals:éhasÉ, butà,è,ì,òandùhave no capital forms in the table. - Typographic punctuation. Curly quotes, the en dash, the em dash, the single-character ellipsis and the bullet.
- Common symbols.
©,®,™and the degree sign°. - Every other script. Cyrillic, Arabic, Hebrew, Chinese, Japanese, Korean, the Indic scripts, and Greek lower case.
The pattern by language follows from the table. German has everything it needs (ä ö ü ß and the capitals), and the Scandinavian letters å, ø and æ are present in both cases. Spanish gets ñ, ¿ and ¡ but not á, í, ó or ú. French gets é, è, à and ù but not ê, â, ô or ç. Portuguese lacks ã, õ and ç. One missing letter is enough to move a message to Unicode.
What is surprisingly present
- Ten Greek capitals. Only the ones that do not resemble a Latin capital have their own positions. The Unicode Consortium's mapping file notes that the intent was to cover upper-case Greek by reusing Latin letters of the same shape, such as A, B and E. That does not help with real Greek text: a Greek alpha typed on a Greek keyboard is a different character from a Latin A, and it is not in the table.
é,è,ñ,Ñ,Çandß, along withÆ,ØandÅin both cases.£,¥,¤and§, plus the inverted¡and¿.
The ç question at position 0x09
Two authoritative sources disagree about one position.
- 3GPP TS 23.038 prints the capital
Çat 0x09. We checked both the 3GPP edition (V20.0.0) and the ETSI edition (V19.0.0). - The Unicode Consortium's mapping file maps 0x09 to the small
ç. Its notes acknowledge that the specification "shows an uppercase C-cedilla glyph at 0x09" and argue that "the language coverage intent is clearly for the lowercase c-cedilla".
In practice the capital reading has won. The default table in Android's GsmAlphabet.java has Ç at that position, and so does the GSM-7 table in Twilio's documentation. The standard's own text also treats the small letter as absent: describing a phone that does not support the optional Turkish table, it says the word "Türkçe" would be displayed as "Türkce".
What this means for you: assume Ç is safe and ç forces Unicode. Our SMS Character Counter follows the 3GPP table. A tool or library generated from the Unicode mapping file will say the opposite about this one character, and that is the likely reason if two calculators disagree about a message containing ç.
National language shift tables
The standard also defines optional national language tables "for adding the special characters of certain languages that cannot be expressed using the GSM default 7 bit alphabet". A header at the start of the message names the language. With a single shift, the escape code then selects from a language-specific table in place of the normal extension table; with a locking shift, a language-specific table replaces the whole basic alphabet. Identifiers exist for 13 languages: Turkish, Spanish (single shift only), Portuguese, Bengali, Gujarati, Hindi, Kannada, Malayalam, Oriya, Punjabi, Tamil, Telugu and Urdu. The header uses capacity, so a single message drops to 155 characters with one of the mechanisms or 152 with both. Support is optional, and the standard warns that a phone without locking-shift support "will present different characters from the ones intended". Do not assume your provider uses these tables: Android's code describes having none enabled as the "common case", and Infobip, which does offer the feature for Turkish, Portuguese and Spanish, adds the caution "Some networks might not support the Language feature." Our counter does not model these tables.
How to tell whether a message is GSM-7
A message is GSM-7 only if every character is in the basic table or the extension table. Checking by eye is unreliable, because a curly apostrophe looks almost identical to a straight one. Paste the text into the SMS Character Counter and it names each character that forces Unicode, with a GSM-7 replacement where a close one exists.
For what happens to the limits once a message leaves GSM-7, see SMS character limits and, for the most common trigger, why one emoji can change the length of an SMS.