LINUX.ORG.RU

Что за кодировка то такая?

 , ,


0

1

Всем привет!

В общем, есть софтина которая написана на Delphi и отправляет AnsiString по TCP. Получает эту строку другая софтина, написанная на Lazarus. Но приходят не совсем валидные данные ибо английские символы сохраняются, а русские заменяются типа так:

Отправлено: COM-порт 

Получено: COM-\u043F\u043E\u0440\u0442

Итого:

  • Что это за формат то такой? Понятно, что UniCode, но от куда он взялся?!
  • Как его правильно преобразовать в читаемый вид? Функции типа UTF8Decode - не работают =(
★★★★

Последнее исправление: AntonyRF (всего исправлений: 1)

подозреваю, что символы больше 0x7F конвертируются в строковое шестнадцатеричное представление, преобразовать - провести обратную процедуру, преобразовать строку в число

Harald ★★★★★
()

Что есть AnsiString в Delphi. В версиях до 2009 – это строка в кодировке, соответствующей локали твоего приложения, скорее всего в CP1251, однако кодировка не обязана быть однобайтной. Начиная с 2009й AnsiString снабжён полем кодировки, а среда выполняет переконвертирование туда-сюда при необходимости. Так что до начала неплохо выяснить, какие байтики идут в сокет.

В Lazarus же строки хранятся в UTF-8. Так что по-хорошему из сокета надо доставать байты и, зная кодировку, преобразовывать в UTF-8, который класть в строку.

Строка выводится в консоль? Какая локаль в принимающей системе?

uuwaan ★★
()
Последнее исправление: uuwaan (всего исправлений: 1)
Ответ на: комментарий от AntonyRF

преобразовать юникодный codepoint 043F в UTF-8 представление

Harald ★★★★★
()

кастану эксперта в области кодировок

#cast saahriktu

Harald ★★★★★
()
Ответ на: комментарий от waker

это ucs-2/utf16

Спасибо мил человек, пробую конвертнуть =)

AntonyRF ★★★★
() автор топика
Ответ на: комментарий от uuwaan

не обязана быть однобайтной.

Нихохо, вот это новость 0_о

Так что до начала неплохо выяснить, какие байтики идут в сокет.

(
  $7B, $22, $61, $63, $74, $69, $6F, $6E, 
  $22, $3A, $22, $72, $65, $61, $64, $22, 
  $2C, $22, $72, $65, $73, $6F, $75, $72, 
  $63, $65, $22, $3A, $22, $67, $75, $69, 
  $64, $22, $7D
)

Строка выводится в консоль? Какая локаль в принимающей системе?

Строка пишется в SQLite =( Отправляющая сторона написана на Delphi XE7, тип данных AnsiString, думаю что кодировка 1251.

Принимающая сторона ARM SoC Linux, кодировка UTF-8

UPDATE: Ща подкину пакетик с русским текстом

(
  $7B, $22, $61, $63, $74, $69, $6F, $6E, 
  $22, $3A, $22, $75, $70, $64, $61, $74, 
  $65, $22, $2C, $22, $69, $64, $22, $3A, 
  $32, $2C, $22, $64, $61, $74, $61, $22, 
  $3A, $7B, $22, $66, $69, $65, $6C, $64, 
  $5F, $31, $22, $3A, $22, $5C, $75, $30, 
  $34, $31, $34, $5C, $75, $30, $34, $33, 
  $30, $22, $2C, $22, $66, $69, $65, $6C, 
  $64, $5F, $32, $22, $3A, $22, $74, $74, 
  $79, $6D, $78, $5C, $75, $30, $34, $34, 
  $31, $30, $22, $2C, $22, $66, $69, $65, 
  $6C, $64, $5F, $33, $22, $3A, $22, $43, 
  $4F, $4D, $2D, $5C, $75, $30, $34, $33, 
  $46, $5C, $75, $30, $34, $33, $45, $5C, 
  $75, $30, $34, $34, $30, $5C, $75, $30, 
  $34, $34, $32, $22, $7D, $7D
)

AntonyRF ★★★★
() автор топика
Последнее исправление: AntonyRF (всего исправлений: 2)
Ответ на: комментарий от AntonyRF

Участки, пишущие и читающие сокет и базу, можешь показать?

uuwaan ★★
()

В си++11 так можно писать строковые литералы в utf-16.

iliyap ★★★★★
()
Ответ на: комментарий от AntonyRF

{«action»:«update»,«id»:2,«data»:{«field_1»:«\u0414\u0430»,«field_2»:«ttymx\u04410»,«field_3»:«COM-\u043F\u043E\u0440\u0442»}}

Ну так тебе уже с сокета приходит вот это вот. Это не кодировка сообщения, это тупо эскейпинг, чтобы строка пролезла в ASCII (в оригинале видимо был уникод, любой формы). Если ее разэскейпить, то значения совпадут с кодепоинтами уникода. Другими словами, надо в этой строке найти последовательности \u???? и заменить их на то, что будет соответствовать числу ???? в твоей целевой кодировке. Если в лазарусе есть функция преращения кодепоинта в строку, то это оно.

str_replace(msg, '\\u0414', unichar_to_string($414)) нужен тебе, образно говоря. Как это будет выглядеть на фрипаскале, и есть ли там регэкспы чтобы это выдрать из текста все значения - я хз.

anonymous
()
Ответ на: комментарий от anonymous

Хм, действительно, сейчас попробую разэскейпить

AntonyRF ★★★★
() автор топика

Короче, нашёл от куда ноги растут. В программе написанной на Delphi была строка

procedure ...;
var
  JsCommand: TJSONObject;
begin
...
    JsCommand.ToJSON;

Вылечилось заменой на JsCommand.ToString, но пока нашёл вынес себе мозг ёклмн =(

AntonyRF ★★★★
() автор топика
Ответ на: комментарий от anonymous

Блин, не поправил. Что характерно просто в Linux всё приходит нормально, стоит запустить под ARM и вижу такую хрень в отладчике:

'{\"action\":\"update\",\"id\":5,\"data\":{\"field_1\":\"'#208#148#208#176'\",\"field_2\":\"ttymxc0\",\"field_3\":\"COM-'#208#159#208#190#209#128#209#130'\"}}'

Отправляется 'Да' = #208#148#208#176

// Тогда как в Lazarus:
ord('Д') - 1044
ord('а') - 1072
AntonyRF ★★★★
() автор топика
Ответ на: комментарий от AntonyRF

Это чистый utf-8, отображенный в виде #ddd. 208 148 это 0xD0 0x94 -> 0x414 -> 1044.

Если я правильно распарсил выхлоп отладчика конечно — мало инфы о твоих действиях, приходится угадывать контекст.

anonymous
()
Ответ на: комментарий от AntonyRF

Вообще, если шлется в сокет для распаковки на той стороне, то странно, что не ToBytes. Абсолютли все ноги могут расти именно отсюда.

anonymous
()
Ответ на: комментарий от anonymous

мало инфы о твоих действиях, приходится угадывать контекст.

Сорян, но чёт ссыкотно раскрывать исходники.

А так по теме, копания продолжаются. В общем уже вижу в отладчике, что всё нормально. Русский текст в UTF8 отправляется из Delphi и приходит в Lazarus, так что тема с передачей данных по сокетам закрыта, но сцуко fpjson не работает на ARM. Проявляется это так:

1. Запускаем в Debian 8 архитектура x86_64 такой код:


var
  jData: TJSONData;
  jObject: TJSONObject; 
begin
    jData := GetJSON(UTF8String('{"test", "Тест мой"}'));

    jObject := TJSONObject(jData);
    Buffer:= jObject.Get('test');   
end; 
И видим в отладчике, что test равен 'Тест мой' т.е. всё хорошо. Теперь же пересоберём проект для Yocto armv7l kernel 3.10.53-1.1.2 - Мы получаем с этим же кодом следующее '???? ???', окей, смотрим по байтам:
3f 3f 3f 3f 20 3f 3f 3f 00 
Wtf? Как такое может быть? 0_о

AntonyRF ★★★★
() автор топика
Ответ на: комментарий от AntonyRF

Ну давай предположим, что fpjson *не* кривой от рождения.

Может от локали зависит чарсет фрипаскальных строк и под arm у тебя LANG=C или что-то подобное? Например fpjson думает, что он в ascii или в latin1, и тогда все русские символы конвертятся в вопросики? Или это вообще не в нем, а в UTF8String() проблема, например.

anonymous
()
Ответ на: комментарий от anonymous

Ох, сейчас среду до последней версии обновляю и посмотрю локаль

AntonyRF ★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.