Автодетект кодировки строки для SMS на Perl

Ежели кто не в курсе, то в SMS используются две основные кодировки символов:

  • default GSM alphabet - 7-битная кодировка, частично совместимая с ASCII (см. ETSI GSM 03.38)
  • UCS-2BE (она же UTF-16BE) - 16-битная кодировка

Т.к. размер сообщения SMS весьма ограничен (140 байт), то иметь возможность автоматически определить кодировку бывает достаточно полезно для разработчика SMS-сервисов. Несмотря на кажущуюся простоту, задачка усложняется, если вспомнить, что в 7-битной кодировке ряд символов представлен ESC-последовательностями.

В общем, простой способ определения кодировки с помощью модуля NetSDS::Util::String:

 

# ==========================================
use NetSDS::Util::String;

# need unicode characters, not byte string  
$text = str_encode($text);

# SMS encoding autodetection
# If text can't be recoded to GSM 03.38 then use UCS-2BE charset

my $gsm0338 = undef;

eval { $gsm0338 = str_recode( $text, "utf-8", "gsm0338" ); };
if ( $@ and !$gsm0338 ) {
  $coding = 2;              # UCS-2BE (16 bit)
} else {
  $coding = 0;              # GSM 03.38 (7bit)
}
$text = str_decode($text);    # convert string back to byte sequence