Как работать с ISO-2022-JP (и другими наборами символов) в обновлении Twitter? - PullRequest
1 голос
/ 26 декабря 2009

Часть моего приложения принимает произвольный текст и публикует его в качестве обновления в Twitter. Все работает нормально, пока не доходит до публикации внешних (не ASCII / UTF7 / 8) наборов символов, тогда все перестает работать.

Например, если кто-то публикует сообщения:
に 投稿 で き る

Это (в моем коде в отладчике Visual Studio) становится:
=? ISO-2022-JP? В? GyRCJEtFajlGJEckLSRrGyhC? =

Гугл сказал мне, что это представляет (минус? Как разделители)

=? ISO-2022-JP - кодировка текста
? B означает, что он закодирован в base64
? GyRCJEtFajlGJEckLSRrGyhC? Является ли закодированная строка

Насколько я могу судить, я не могу понять, как опубликовать эту строку в качестве обновления в Twitter с ее оригинальными японскими символами. В настоящее время отправка '=? ISO-2022-JP? B? GyRCJEtFajlGJEckLSRrGyhC? =' В Twitter приведет именно к тому, что сообщение будет опубликовано. Я также попытался разбить строку на части, как описано выше, используя System.Text.Encoding для преобразования в UTF8 из ISO-2022-JP и наоборот, с декодированием base64 и без него. Кроме того, я поигрался с кодировкой URL-адреса обновления статуса следующим образом:


string[] bits = tweetText.Split(new char[] { '?' });
if (bits.Length >= 4)
{
textEncoding = System.Text.Encoding.GetEncoding(bits[1]);
xml = oAuth.oAuthWebRequest(TwitterLibrary.oAuthTwitter.Method.POST, url, "status=" +   System.Web.HttpUtility.UrlEncode(decodedText, textEncoding)); 
}

Независимо от того, что я делаю, результаты никогда не возвращаются к норме.

EDIT: Понял в конце. Для тех, кто следит за домом, это было довольно близко к ответу, указанному ниже в конце. Просто отладчик Visual Studios направлял меня в неверном направлении, и я обнаружил ошибку в библиотеке Twitter. Конечный результат был таким:

<code>
decodedText = textEncoding.GetString(System.Convert.FromBase64String(bits[3]));
byte[] originalBytes = textEncoding.GetBytes(decodedText);
byte[] utfBytes = System.Text.Encoding.Convert(textEncoding, System.Text.Encoding.UTF8, originalBytes);
// now, back to string form
decodedText = System.Text.Encoding.UTF8.GetString(utfBytes);

Спасибо всем.

Ответы [ 2 ]

7 голосов
/ 27 декабря 2009

В результате вы получили искомый результат:

using System;
using System.Text;

class Program {
  static void Main(string[] args) {
    string input = "に投稿できる";
    Console.WriteLine(EncodeTwit(input));
    Console.ReadLine();
  }
  public static string EncodeTwit(string txt) {
    var enc = Encoding.GetEncoding("iso-2022-jp");
    byte[] bytes = enc.GetBytes(txt);
    char[] chars = new char[(bytes.Length * 3 + 1) / 2];
    int len = Convert.ToBase64CharArray(bytes, 0, bytes.Length, chars, 0);
    return "=?ISO-2022-JP?B?" + new string(chars, 0, len) + "?=";
  }
}

Стандарты отличные, есть из чего выбирать. ISO никогда не разочаровывает, существует не менее 3 кодировок ISO-2022-JP. Если у вас возникли проблемы, попробуйте также кодировки 50221 и 50222.

2 голосов
/ 26 декабря 2009

Ваше понимание того, как закодирован текст, кажется правильным. В питоне

'GyRCJEtFajlGJEckLSRrGyhC'.decode('base64').decode('ISO-2022-JP')

возвращает правильную строку Юникода. Обратите внимание, что вам нужно сначала декодировать base64, чтобы получить кодированный в ISO-2022-JP текст.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...