Что нового

Конвертация UCS-2 HEX (UTF-16) в кириллицу

Latoid

Знающий
Сообщения
95
Репутация
11
Здравствуйте.
Пишу программу приема SMS приходящих на 3G модем.
SMS приходят в кодировке UCS-2 hex (это почти тоже самое, что и UTF-16)
Пример такой строки:
041F04400438043204350442
Помогите написать функцию перекодировки во что-нибудь читаемое.
Вроде тут есть пример; да на другом языке :(
Спасибо
 

winstan

Эксплотатор)
Сообщения
406
Репутация
79
Код:
Func UCS2ToString($intext)
	$res=""
	$hex="0x"
	if (StringLen ($intext)=0) or (Mod(StringLen ($intext),2)<>0) Then
		SetError(1)
		Return
	EndIf
	$num=StringLen ($intext)/2
	Local $buffer[$num]
	For $i=0 to $num-1
		$buffer[$i]=StringMid($intext,$i*2+1,2)

		Switch StringLeft( $buffer[$i], 1 )
			Case "1"
			$buffer[$i]=StringReplace($buffer[$i],1,"C")
			Case "2"
			$buffer[$i]=StringReplace($buffer[$i],1,"D")
			Case "3"
			$buffer[$i]=StringReplace($buffer[$i],1,"E")
			Case "4"
			$buffer[$i]=StringReplace($buffer[$i],1,"F")
		EndSwitch
		if $buffer[$i]<>4 Then $hex&=$buffer[$i]
	Next
	Return BinaryToString($hex)
EndFunc
 
Автор
L

Latoid

Знающий
Сообщения
95
Репутация
11
Огромное спасибо! :beer:


Добавлено:
Сообщение автоматически объединено:

Немного поторопился.
Функция конвертит только одно слово до пробела.
Вот пример стандартных 4 СМС от МТС с сообщением о балансе:

----------------
0414043B044F0020043F0440043E043204350440043A0438002004310430043B0430043D04410430002004380441043F043E043B044C0437044304390442043500200441043B043504340443044E0449043804350020043104350441043F043B04300442043D044B04350020043A043E043C0430043D0434044B003A0020
----------------
04110430043B0430043D04410020002A0031003000300023002C0020041F043504400438043E04340438044704350441043A043804350020043F0430043A04350442044B0020002A003100300030002A00310023002C0020042004300437043E0432044B04350020043F0430043A04350442044B0020
----------------
002A003100300030002A00320023002C0020041A044004350434043804420020002A003100300030002A00330023002C0020043104350441043F043B04300442043D044B0439002004370432043E043D043E043A0020043D043000200031003100310020002804340430043B0435043500200031002C0020
----------------
04340430043B04350435002000310029
----------------

Можете доработать? Спасибо
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Попробуй
Код:
$dec="0414043B044F0020043F0440043E043204350440043A0438002004310430043B0430043D04410430002004380441043F043E043B044C0437044304390442043500200441043B043504340443044E0449043804350020043104350441043F043B04300442043D044B04350020043A043E043C0430043D0434044B003A002004110430043B0430043D04410020002A0031003000300023002C0020041F043504400438043E04340438044704350441043A043804350020043F0430043A04350442044B0020002A003100300030002A00310023002C0020042004300437043E0432044B04350020043F0430043A04350442044B0020002A003100300030002A00320023002C0020041A044004350434043804420020002A003100300030002A00330023002C0020043104350441043F043B04300442043D044B0439002004370432043E043D043E043A0020043D043000200031003100310020002804340430043B0435043500200031002C002004340430043B04350435002000310029"

$unicodetotext=_PDU_UCS2_ASCII($dec)

ConsoleWrite("USC2 в ASCII -> "&$unicodetotext & @CRLF)

Func _PDU_UCS2_ASCII($s)
	;Преобразует UCS2 в строку.
	Local $result
	For $i=1 To StringLen($s) Step 4
		$k=Dec(StringMid($s,$i,4))
		If $k=1025 Then
			$k=168 ;Ё
		ElseIf $k=1105 Then
			$k=184 ;ё
		ElseIf $k>=1040 Then
			$k-=848 ;~ 	$k=$k-1040+192
		EndIf
		$result&=Chr($k)
	Next
Return $result
EndFunc



Добавлено:
Сообщение автоматически объединено:

Если надо, вот обратная функция
Код:
Func _PDU_ASCII_USC2($s)
	;Функция кодирует входящий текст в кодировку USC2
	Local $result
	For $i=1 to StringLen($s)
		$k=Asc(StringMid($s,$i,1))
		If $k=168 Then
			$k=1025 ;Ё
		ElseIf $k=184 Then
			$k=1105 ;ё
		ElseIf $k>=192 Then
			$k+=848 ;~ 	$k=$k+1040-192 ;// НЕПОСРЕДСТВЕННО преобразуем + 410h - C0h
		EndIf
		$result&=Hex($k,4)
	Next
	Return $result
EndFunc



Добавлено:
Сообщение автоматически объединено:

Есть еще функции для упакованных 7_bits сообщений и 8 битных :whistle:
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Это 8 битовое кодирование
Код:
#cs ----------------------------------------------------------------------------
	При 8-ми битовом кодировании применяется  INTEL ASCII-HEX таблица и сообщение в таком случае не может содержать более 140 символов.

	_PDU_ASCII_8bit($s) ;Кодирует сообщение

	_PDU_8bit_ASCII($s) ;Декодирует сообщение

#ce ----------------------------------------------------------------------------

;~ $t="Privet"
;~ $code=_PDU_ASCII_8bit($t)
;~ $encode=_PDU_8bit_ASCII($code)

;~ ConsoleWrite($code & @CRLF)
;~ ConsoleWrite($encode & @CRLF)


Func _PDU_ASCII_8bit($s)
	Local $result
	For $i = 1 To StringLen($s)
		$result &= Hex(Asc(StringMid($s, $i, 1)), 2)
	Next
	Return $result
EndFunc   ;==>_PDU_ASCII_8bit

Func _PDU_8bit_ASCII($s)
	Local $result
	For $i = 1 To StringLen($s) Step 2
		$result &= Chr("0x" & StringMid($s, $i, 2))
	Next
	Return $result
EndFunc   ;==>_PDU_8bit_ASCII


Это 7 битовое
Код:
#cs -----------------------------------------------------------------------------------------------
	_PDU_ASCII_7bit($Text) - Кодирует
	_PDU_7bit_ASCII($PDU) - Декодирует
#ce -----------------------------------------------------------------------------------------------

;~ ================================================================================================
;~ ================================================================================================
Func _PDU_ASCII_7bit($s) ;Кодирует
	Local $bin_long, $Result
	While $s
		$bin_long &= __Dec2Bin(Asc(StringRight($s, 1)))
		$s = StringTrimRight($s, 1)
	WEnd
	While $bin_long > 0 ;Это важно
		$Result &= __BinToHex(StringRight($bin_long, 8))
		$bin_long = StringTrimRight($bin_long, 8)
	WEnd
	Return $Result
EndFunc   ;==>_PDU_ASCII_7bit
;~ ================================================================================================
;~ ================================================================================================
Func _PDU_7bit_ASCII($s) ;Декодирует
	Local $bin_long, $Result
	While $s
		$bin_long &= StringFormat('%08s', __Dec2Bin(Dec(StringRight($s, 2))))
		$s = StringTrimRight($s, 2)
	WEnd
	While $bin_long > 0 ;Это важно
		$Result &= Chr("0x" & __BinToHex(StringRight($bin_long, 7)))
		$bin_long = StringTrimRight($bin_long, 7)
	WEnd
	Return $Result
EndFunc   ;==>_PDU_7bit_ASCII
;~ ================================================================================================
;~ ================================================================================================

;~ ================================================================================================
Func __Dec2Bin($decimal)
	Local $binary
	While $decimal > 0
		$binary = String(Mod($decimal, 2)) & $binary
		$decimal = Int($decimal / 2)
	WEnd
	Return $binary
EndFunc   ;==>__Dec2Bin

Func __BinToHex($Bin)
	Local $b, $c, $d, $e, $Result
	$b = StringLen($Bin)
	For $i = 1 To $b
		$c = StringMid($Bin, $i, 1)
		$d = $b - $i
		$e = $c * (2 ^ $d)
		$Result = $Result + $e
	Next
	$Result = Hex($Result, 2)
	Return $Result
EndFunc   ;==>__BinToHex
;~ ================================================================================================
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
ИМХО, надо добавить эти полезные функции в Encoding.au3
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
ИМХО, эти функции никому кроме тех кто отправляет/принимают SMS больше не нужны. Они, так сказать, узкоспециализированы. Но CreatoR может конечно добавить :smile:
 
Верх