Расшифровка цитируемого печатного сообщения

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

Закодированное сообщение ISO-2022-JP в кавычках для печати:

"=82=B1=82=EA=82=CD=92P=82=C8=82=E9=83e=83X=83g=82=C5=82=B7=82=DD=82=C8=82=B3=\r\n=82=F1=81A=82=B1 =82=F1=82=C9=82=BF=82=CD"

Код для декодирования Quoted Printable:

 private static string Decode(string input, string bodycharset)
    {
        var i = 0;
        var output = new List<byte>();
        while (i < input.Length)
        {
            if (input[i] == '=' && input[i + 1] == '\r' && input[i + 2] == '\n')
            {
                //Skip
                i += 3;
            }
            else if (input[i] == '=')
            {
                string sHex = input;
                sHex = sHex.Substring(i + 1, 2);
                int hex = Convert.ToInt32(sHex, 16);
                byte b = Convert.ToByte(hex);
                output.Add(b);
                i += 3;
            }
            else
            {
                output.Add((byte)input[i]);
                i++;
            }
        }
        if (String.IsNullOrEmpty(bodycharset))
            return Encoding.UTF8.GetString(output.ToArray());
        else
            return Encoding.GetEncoding(bodycharset).GetString(output.ToArray());
    }

Окончательный результат:

・ア・・・ヘ・P・ネ・・・e・X・g・ナ・キ・ン・ネ・ウ・・・A・ア・・・ノ・ソ・ヘ

Любые идеи, чтобы решить эту проблему?


person user845405    schedule 09.01.2012    source источник
comment
для вашей кодировки.. вы используете Encoding.GetEncoding(ISO-2022-JP)   -  person MethodMan    schedule 10.01.2012
comment
Отвечает ли это на ваш вопрос? C#: класс для декодирования кодировки Quoted-Printable?   -  person Jon Schneider    schedule 19.03.2020


Ответы (5)


попробуй это

var str = Decode(inp, "Shift_JIS");

or

var str = Decode(inp, "sjis");
person BLUEPIXY    schedule 10.01.2012

Вы можете использовать трюк, продемонстрированный в следующей статье:

Таким образом, вы можете быть чем-то вроде:

private static string Decode(string input, string bodycharset)
{
    Attachment attachment = Attachment.CreateAttachmentFromString("", "=?"+bodycharset+"?"+input+"?=");
    return (attachment.Name);
}

Также необходимо добавить:

using System.Net.Mail;

Надеюсь, это поможет :-)

person Qorbani    schedule 09.01.2012
comment
Когда я использую предоставленную вами функцию декодирования, она возвращает мне эту строку =?iso-2022-jp?=8D=C4=82=D1=83C=83=93=83o=83E=83=93=83h=83=81= 81[=83=8B=82=CC=83e=83X=83g =8D=C4=82=D1=83C=83=93=83o=83E=83=93=83h=83=81=81[=83= 8B=82=CC=83e=83X=83g =8D=C4=82=D1=83C=83=93=83o=83E=83=93=83h=83=81=81[=83=8B=82=CC =83e=83X=83g =8D=C4=82=D1=83C=83=93=83o=83E=83=93=83h=83=81=81[=83=8B=82=CC=83e=83X= 83g =8D=C4=82=D1=83C=83=93=83o=83E=83=93=83h=83=81=81[=83=8B=82=CC=83e=83X=83g - person user845405; 10.01.2012
comment
Извините, я попробовал это сам, и он показывает мне то же самое, затем я изменил его на: Attachment.CreateAttachmentFromString(, =? + input + ?B? + bodycharset + ?=, Encoding.GetEncoding(input), null); и у меня что-то есть, но я не уверен, правильно это или нет?! - person Qorbani; 10.01.2012
comment
Также я нашел это: codeproject.com/KB/IP/Pop3MimeClient.aspx взгляните на его класс QuotedPrintable! Он реализует почти то же самое, что и вы, но с RegEx. - person Qorbani; 10.01.2012

Будет ли что-то похожее на это работать? просто Суду закодировал такое быстро

Encoding encoding = Encoding.GetEncoding("iso-2022-jp");
byte[] bytes  = encoding.GetBytes(output);
string uuEncoded = Convert.ToBase64String(bytes);
person MethodMan    schedule 09.01.2012
comment
Нет, это не работает. он выдает ошибку компиляции. Encoding.GetBygtes имеет недопустимые аргументы. - person user845405; 10.01.2012

Эта цитируемая печатная версия спасла мне жизнь. Это работает как шарм!

public static byte[] FromHex(byte[] hexData)
    {
        if (hexData == null)
        {
            throw new ArgumentNullException("hexData");
        }

        if (hexData.Length < 2 || (hexData.Length / (double)2 != Math.Floor(hexData.Length / (double)2)))
        {
            throw new Exception("Illegal hex data, hex data must be in two bytes pairs, for example: 0F,FF,A3,... .");
        }

        MemoryStream retVal = new MemoryStream(hexData.Length / 2);
        // Loop hex value pairs
        for (int i = 0; i < hexData.Length; i += 2)
        {
            byte[] hexPairInDecimal = new byte[2];
            // We need to convert hex char to decimal number, for example F = 15
            for (int h = 0; h < 2; h++)
            {
                if (((char)hexData[i + h]) == '0')
                {
                    hexPairInDecimal[h] = 0;
                }
                else if (((char)hexData[i + h]) == '1')
                {
                    hexPairInDecimal[h] = 1;
                }
                else if (((char)hexData[i + h]) == '2')
                {
                    hexPairInDecimal[h] = 2;
                }
                else if (((char)hexData[i + h]) == '3')
                {
                    hexPairInDecimal[h] = 3;
                }
                else if (((char)hexData[i + h]) == '4')
                {
                    hexPairInDecimal[h] = 4;
                }
                else if (((char)hexData[i + h]) == '5')
                {
                    hexPairInDecimal[h] = 5;
                }
                else if (((char)hexData[i + h]) == '6')
                {
                    hexPairInDecimal[h] = 6;
                }
                else if (((char)hexData[i + h]) == '7')
                {
                    hexPairInDecimal[h] = 7;
                }
                else if (((char)hexData[i + h]) == '8')
                {
                    hexPairInDecimal[h] = 8;
                }
                else if (((char)hexData[i + h]) == '9')
                {
                    hexPairInDecimal[h] = 9;
                }
                else if (((char)hexData[i + h]) == 'A' || ((char)hexData[i + h]) == 'a')
                {
                    hexPairInDecimal[h] = 10;
                }
                else if (((char)hexData[i + h]) == 'B' || ((char)hexData[i + h]) == 'b')
                {
                    hexPairInDecimal[h] = 11;
                }
                else if (((char)hexData[i + h]) == 'C' || ((char)hexData[i + h]) == 'c')
                {
                    hexPairInDecimal[h] = 12;
                }
                else if (((char)hexData[i + h]) == 'D' || ((char)hexData[i + h]) == 'd')
                {
                    hexPairInDecimal[h] = 13;
                }
                else if (((char)hexData[i + h]) == 'E' || ((char)hexData[i + h]) == 'e')
                {
                    hexPairInDecimal[h] = 14;
                }
                else if (((char)hexData[i + h]) == 'F' || ((char)hexData[i + h]) == 'f')
                {
                    hexPairInDecimal[h] = 15;
                }
            }

            // Join hex 4 bit(left hex cahr) + 4bit(right hex char) in bytes 8 it
            retVal.WriteByte((byte)((hexPairInDecimal[0] << 4) | hexPairInDecimal[1]));
        }

        return retVal.ToArray();
    }
    public static byte[] QuotedPrintableDecode(byte[] data)
    {
        if (data == null)
        {
            throw new ArgumentNullException("data");
        }

        MemoryStream msRetVal = new MemoryStream();
        MemoryStream msSourceStream = new MemoryStream(data);

        int b = msSourceStream.ReadByte();
        while (b > -1)
        {
            // Encoded 8-bit byte(=XX) or soft line break(=CRLF)
            if (b == '=')
            {
                byte[] buffer = new byte[2];
                int nCount = msSourceStream.Read(buffer, 0, 2);
                if (nCount == 2)
                {
                    // Soft line break, line splitted, just skip CRLF
                    if (buffer[0] == '\r' && buffer[1] == '\n')
                    {
                    }
                    // This must be encoded 8-bit byte
                    else
                    {
                        try
                        {
                            msRetVal.Write(FromHex(buffer), 0, 1);
                        }
                        catch
                        {
                            // Illegal value after =, just leave it as is
                            msRetVal.WriteByte((byte)'=');
                            msRetVal.Write(buffer, 0, 2);
                        }
                    }
                }
                // Illegal =, just leave as it is
                else
                {
                    msRetVal.Write(buffer, 0, nCount);
                }
            }
            // Just write back all other bytes
            else
            {
                msRetVal.WriteByte((byte)b);
            }

            // Read next byte
            b = msSourceStream.ReadByte();
        }

        return msRetVal.ToArray();
    }
person Gonzalo Gallotti    schedule 15.02.2012
comment
Лучше иметь ввод и вывод в виде строки, поскольку при преобразовании из строки в массив байтов или наоборот возникает путаница и крайние случаи. - person Dan W; 26.09.2012

Опаздываю на вечеринку, но у меня есть решение этой надоедливой задачи.

Я нашел решение по следующей ссылке: http://sourceforge.net/apps/trac/syncmldotnet/wiki/Quoted%20Printable

Если вам просто нужно декодировать QP, вставьте в свой код эти три функции по ссылке выше:

    HexDecoderEvaluator(Match m)
    HexDecoder(string line)
    Decode(string encodedText)

А потом просто:

var humanReadable = Decode(myQPString);

В любом случае ссылка также предоставляет функции для кодирования.

Наслаждаться

person pizzaboy    schedule 17.09.2013