Работа с необычными ответами на текстовые сообщения - PullRequest
0 голосов
/ 24 апреля 2018

Я написал систему планирования встреч, которая (помимо прочего) отправляет SMS-напоминание за день до назначенной встречи. Он просит пользователя подтвердить свое присутствие на встрече, ответив «ОК» на текст.

Там, где люди отвечают, это обычно работает хорошо и исключает огромную ручную нагрузку. Сейчас я нахожусь в процессе исправления пары дефектов (к счастью, их мало и они мало влияют), но иногда я вижу ответы @u{some string}. У меня нет правил, чтобы проанализировать это, поэтому они попадают в корзину недопустимых ответов для последующего ручного наблюдения.

Сегодня я увидел ответ, который выглядел следующим образом:

@ u004f006b

На этом этапе я почти уверен, что @u обозначает, что ниже следует Unicode (аналог обозначения \ u в C #), поэтому, исходя из этого предположения, я получаю следующее:

U + 004F => десятичный 79 => O (заглавные буквы)

U + 006B => десятичный 107 => k (строчные)

Ответственная компания говорит мне, что сообщение попадает на их серверы таким образом, так что это должно быть проблема клиента, верно? Я посмотрел в своем приложении для отправки SMS (ChompSMS на Android 7.x) и не вижу ничего, что указывало бы на его явную отправку в Unicode против ASCII, поэтому мне интересно, как это происходит?

Я вытащил 10 случайных ответов, которые начинались с этого обозначения Unicode, из базы данных и попытался написать что-то, чтобы справиться с ними. Далее следует моя наивная попытка:

using System;
using System.Text;

namespace CharConversion
{
    class Program
    {
        static void Main()
        {
            string[] unicodeResponses = new string[]
            {
                "@U00430061006e20190074002000620065002000610062006c006500200074006f002000620065002000740068006500720065",
                "@U004f006b002000bf00bf",
                "@U004f006b002000bf00bf",
                "@U004f004b002000bf00bf",
                "@U004f006b002000bf00bf",
                "@U00d2006b",
                "@U004f004b",
                "@U004f006b00610079002000bf00bf0020",
                "@U004f004b",
                "@U004f006b00bf00bf00bffffd"
            };

            foreach (string unicodeResponse in unicodeResponses)
            {
                string characters2 = UnicodeCodePointsToString(unicodeResponse);
                Console.WriteLine("'{0}' is '{1}' in plain text", unicodeResponse, characters2);
            }

            Console.Read();
        }

        private static string UnicodeCodePointsToString(string unicodeResponse)
        {
            string[] characterByteValues = SplitStringEveryN(unicodeResponse.Substring(2), 4);
            char[] characters = new char[characterByteValues.Length];

            for (int i = 0; i < characterByteValues.Length; i++)
            {
                int ordinal = Int32.Parse(characterByteValues[i], System.Globalization.NumberStyles.HexNumber);
                characters[i] = (char) ordinal;
            }

            return new string(characters);
        }

        private static string[] SplitStringEveryN(string input, int splitLength)
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < input.Length; i++)
            {
                if (i % splitLength == 0)
                {
                    sb.Append(' ');
                }
                sb.Append(input[i]);
            }

            string[] returnValue = sb.ToString().TrimStart().Split(' ');
            return returnValue;
        }
    }
}

Мои вопросы:

  1. Почему это происходит в первую очередь?

  2. С кодом - я что-то упускаю здесь? Например. Есть ли в Framework что-то, что уже может справиться с этим для меня, или есть какой-то явный недостаток, который могут увидеть люди, которые знают все о Unicode? Есть ли что-то, что я могу сделать лучше?

  3. Некоторые из пунктов кода по-прежнему отображаются как перевернутые вопросы (я подозреваю, что это смайлики) - есть ли способ справиться с ними?

РЕДАКТИРОВАТЬ 2018-04-26 Записка для потомков

(я собирался поместить это в комментарий, но это выглядело ужасно, независимо от того, что я с ним сделал)

Я посмотрел на ссылку в принятом ответе, и хотя код более лаконичен, чем мой, выходные данные в конце идентичны, включая перевернутые знаки вопроса (и подозреваемые глифы - смайлики). Еще немного прочтения о различиях между Unicode и UCS2 можно найти здесь и Статья в Википедии также стоит прочитать:

TL; DR

  • UCS-2 устарел и с тех пор был заменен на UTF-16. UCS-2 является схема кодирования с фиксированной шириной, в то время как UTF-16 является кодированием с переменной шириной схема
  • Приложения с поддержкой UTF-16 могут читать файлы UCS-2, но не наоборот
  • UTF-16 поддерживает сценарии справа налево, в то время как UCS-2 не
  • UTF-16 поддерживает нормализацию, в то время как UCS-2 не

Ответы [ 2 ]

0 голосов
/ 24 апреля 2018

Вот более простой метод:

using System;
using System.Text;

namespace CharConversion
{
    class Program
    {
        static void Main()
        {
            string[] unicodeResponses = new string[]
            {
                "@U00430061006e20190074002000620065002000610062006c006500200074006f002000620065002000740068006500720065",
                "@U004f006b002000bf00bf",
                "@U004f006b002000bf00bf",
                "@U004f004b002000bf00bf",
                "@U004f006b002000bf00bf",
                "@U00d2006b",
                "@U004f004b",
                "@U004f006b00610079002000bf00bf0020",
                "@U004f004b",
                "@U004f006b00bf00bf00bffffd"
            };

            string message = "";

            foreach (string unicodeResponse in unicodeResponses)
            {
                for (int i = 2; i < unicodeResponse.Length; i += 4)
                {
                    message += (char)Int16.Parse(unicodeResponse.Substring(i, 4), System.Globalization.NumberStyles.HexNumber);
                }
            }
            Console.WriteLine(message);
            Console.Read();
        }


    }
}
0 голосов
/ 24 апреля 2018

SMS-сообщение может быть закодировано несколькими кодировками.К ним относятся 7-битный (GSM-7), 8-битный и 16-битный (UCS2).Хотя большинство программ SMS кодируют сообщения в наименее расточительной кодировке - нет ничего недопустимого в использовании 16-битной, даже если все символы попадают в диапазон других кодировок.Вот и я предполагаю, что происходит в вашем случае.Конечно, sms-сообщения передаются в виде байтов, а не u004f006b строк, поэтому вопрос о том, почему он представлен таким образом, зависит от инструментов, которые вы используете \ от третьих сторон, с которыми вы работаете.

Что касается вашего кода синтаксического анализа.Предполагается, что строка находится в UTF-16 (внутреннее представление строки C #), но если вышеприведенное верно, кодировка UCS2.Это очень похоже на UTF-16, но не совсем то же самое.Я не совсем квалифицирован, чтобы обсуждать различия, но вы можете посмотреть, например, этот ответ , чтобы найти некоторые подсказки о том, как вы можете работать с ним.Это также может быть причиной того, что некоторые символы декодируются неправильно.

...