РОР3 проблема с кодировкой писем

Язык Visual Basic на платформе .NET.

Модераторы: Ramzes, Sebas

VAngel
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 81
Зарегистрирован: 13.01.2005 (Чт) 0:10
Откуда: 2:5030

РОР3 проблема с кодировкой писем

Сообщение VAngel » 09.02.2007 (Пт) 20:23

Всем привет.

Есть одна проблема. Пишу сейчас прогу которая будет анализировать почту в почтовом ящике и выдерать из нее служебную информацию, столкнулся с одной пробблеммой и чего то никак не могу ее решить, весь нет уже облазил ничего не нашол.

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

Принятую информация обрабатываю вот таким кодом:

Код: Выделить всё
    Private Function ReciveCommand(ByRef Stream As System.Net.Sockets.NetworkStream) As String

        Dim str1251 As String = ""
        Dim str866 As String = ""
        Dim strASCII As String = ""
        Dim strDEFAULT As String = ""
        Dim strUNICODE As String = ""
        Dim strUTF32 As String = ""
        Dim strUTF7 As String = ""
        Dim strUTF8 As String = ""
        Dim str As String = ""

        Dim LastChar As String = ""

        Dim Chr(0 To 4096) As Char
        Dim ReciveBytes(0 To 4096) As Byte

        Dim Decoder1251 As System.Text.Decoder
        Decoder1251 = System.Text.Encoding.GetEncoding(1251).GetDecoder

        Dim Decoder866 As System.Text.Decoder
        Decoder866 = System.Text.Encoding.GetEncoding(866).GetDecoder

        Do
            Stream.Read(ReciveBytes, 0, 4096)

            strASCII = System.Text.Encoding.ASCII.GetString(ReciveBytes)
            strDEFAULT = System.Text.Encoding.Default.GetString(ReciveBytes)
            strUNICODE = System.Text.Encoding.Unicode.GetString(ReciveBytes)
            strUTF32 = System.Text.Encoding.UTF32.GetString(ReciveBytes)
            strUTF7 = System.Text.Encoding.UTF7.GetString(ReciveBytes)
            strUTF8 = System.Text.Encoding.UTF8.GetString(ReciveBytes)

            'Таблица 1251
            Decoder1251.GetChars(ReciveBytes, 0, 4096, Chr, 0)
            For Each c As Char In Chr
                str1251 += c.ToString()
            Next

            'Таблица 866
            System.Array.Clear(Chr, 0, 4096)
            Decoder866.GetChars(ReciveBytes, 0, 4096, Chr, 0)
            For Each c As Char In Chr
                str866 += c.ToString()
            Next

            For Each b As Byte In ReciveBytes
                str += Microsoft.VisualBasic.Chr(CInt(b)).ToString()
            Next

            LastChar = str1251.Substring(str1251.Length - 1, 1)
        Loop While (Not LastChar = Microsoft.VisualBasic.Strings.Chr(13))

        Return str1251
    End Function



На выходе получаю:
Код: Выделить всё
str1251 = ... "Subject: =?windows-1251?B?zMjQIMLAzCDIIMLA2MXM0yDEzszT?=" ...
str866 = ... "Subject: =?windows-1251?B?zMjQIMLAzCDIIMLA2MXM0yDEzszT?=" ...
strASCII = ... "Subject: =?windows-1251?B?zMjQIMLAzCDIIMLA2MXM0yDEzszT?=" ...
strDEFAULT = ... "Subject: =?windows-1251?B?zMjQIMLAzCDIIMLA2MXM0yDEzszT?=" ...
strUTF32 = ... "" ... 'Здесь вооще ничего нет только квадраты
strUTF7 = ... "Subject: =?windows-1251?B?zMjQIMLAzCDIIMLA2MXM0yDEzszT?=" ...
strUTF8 = ... "Subject: =?windows-1251?B?zMjQIMLAzCDIIMLA2MXM0yDEzszT?=" ...
strUNICODE = ..."???›Я идиот! Убейте меня, кто-нибудь!??†Я идиот! Убейте меня, кто-нибудь!Я идиот! Убейте меня, кто-нибудь!Я идиот! Убейте меня, кто-нибудь!Я идиот! Убейте меня, кто-нибудь!Я идиот! Убейте меня, кто-нибудь!Я идиот! Убейте меня, кто-нибудь!‹Я идиот! Убейте меня, кто-нибудь!Я идиот! Убейте меня, кто-нибудь!Я идиот! Убейте меня, кто-нибудь!Я идиот! Убейте меня, кто-нибудь!Я идиот! Убейте меня, кто-нибудь!???›Я идиот! Убейте меня, кто-нибудь!????"...
str = ... "Subject: =?windows-1251?B?zMjQIMLAzCDIIMLA2MXM0yDEzszT?=" ...


Что делать не знаю... как нормально получать русский язык? =(

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 09.02.2007 (Пт) 20:54

Только что эту тему разжевали Antonariy и CodeName33 в главном форуме. Закрываю.
Изображение

Sebas
Неуловимый Джо
Неуловимый Джо
Аватара пользователя
 
Сообщения: 3626
Зарегистрирован: 12.02.2002 (Вт) 17:25
Откуда: столько наглости такие вопросы задавать

Сообщение Sebas » 10.02.2007 (Сб) 10:51

На Code Project есть пример Mime Parser`a. Очень рекомендую.
- Я никогда не понимал, почему они приходят ко мне чтобы умирать?

sebas<-@->mail.ru

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 11.02.2007 (Вс) 16:36

VAngel в ЛС писал(а):Приветствую, будь добор запости позалуста сообщение в конференцию "РОР3 проблема с кодировкой писем", я там подробно все написал, или открой что бы можно было запостить

Дальше сообщение:


В общем покопался я по форуму, по нету полазил. после всех изысканий выяснилось что строки в писмах кодируются двумя способами
Base64 "Mail =?koi8-r?B?58/T1PTF09Q=?= <frafubgkfxcw@otaa.com>" как в этой строке, и
Quoted-Printable "=?windows-1251?Q?=E8=E7=EC=E5=ED=E5=ED=E8=FF?= =?windows-1251?Q?=ED=E0?= =?windows-1251?Q?=F4=EE=F0=F3=EC=E5?= ( Atfix.=?windows-1251?Q?COM=99?="
Как кодируется Base64 я не знаю, боюсь ошибиться но мне кажется что Base64 это UUE кодирование знакомое мне еще по Fido
, а Quoted-Printable это кодироввание при котором каждый символ заменяеться на его 16 битное представление, подробней об этом можно
почитать тут http://www.mailinfo.ru/story02/08/19/5202149.

Написал несколько функий для декдирования сообщений, достаточно не тестировал но пока все вроде нормально работает

Эта функция центральная, принимает строку по типу тех которые я привел для примера
вводим Mail "=?koi8-r?B?58/T1PTF09Q=?= <frafubgkfxcw@otaa.com>"
а на выходе получаем
"Mail ГостТест <frafubgkfxcw@otaa.com>"
вводим "=?windows-1251?Q?=E8=E7=EC=E5=ED=E5=ED=E8=FF?= =?windows-1251?Q?=ED=E0?= =?windows-1251?Q?=F4=EE=F0=F3=EC=E5?= ( Atfix.=?windows-1251?Q?COM=99?="
а на выходе получаем "изменения на форуме ( Atfix.COM™"

Код: Выделить всё
Private Function GetStringFromTextWhithRegex(ByRef IncomingString) As String
        Dim RetString As String = IncomingString
        Dim RegexString As String
        Dim CheckCodingString As String
        Dim CodePageString As String
        ' Определяем количество закодированых строк в тексте
        Dim Reg As System.Text.RegularExpressions.Regex
        Reg = New System.Text.RegularExpressions.Regex("\=\?[A-Za-z0-9-]+\?.\?[A-Za-z0-9-=/_!]+\?\=")
        Dim MathCol As System.Text.RegularExpressions.MatchCollection = Reg.Matches(RetString)
        ' Перебираем все кодированые вхождения в текст и разбираем на куски
        For Each Mth As System.Text.RegularExpressions.Match In MathCol
            ' Определяем кодировку что бы потом нормально отображался русский язык
            Reg = New System.Text.RegularExpressions.Regex("\=\?[A-Za-z0-9-]+\?.\?")
            CodePageString = Reg.Match(Mth.Value).ToString()
            CodePageString = CodePageString.Substring(2, CodePageString.Length - 5)
            ' Определяем строку которую надо раскодировать
            Reg = New System.Text.RegularExpressions.Regex("\?.\?[A-Za-z0-9-=/_!]+\?\=")
            RegexString = Reg.Match(Mth.Value).ToString()
            ' Здесь определяем символ который определяет кодировку строки
            CheckCodingString = RegexString.Substring(1, 1).ToLower()
            If CheckCodingString = "b" Then
                ' Символ b значит что кодирование в Base64
                RegexString = RegexString.Substring(3, RegexString.Length - 5)
                RegexString = ConvertBase64Coding(RegexString, CodePageString)
            ElseIf CheckCodingString = "q" Then
                ' Символ q значит что кодирование в quoted-printable
                RegexString = RegexString.Substring(3, RegexString.Length - 5)
                RegexString = ConvertQuotedPrintableCoding(RegexString, CodePageString)
            End If
            RetString = RetString.Replace(Mth.Value, RegexString)
        Next
        Return RetString
    End Function


Эта функция служит для декодирования Quoted-Printable
Код: Выделить всё
    Private Function ConvertQuotedPrintableCoding(ByRef IncomingString As String, ByRef CodePage As String) As String
        Dim ReturnString As String = ""
        Dim i As Integer = 0
        Dim TempString As String
        Dim TempInteger As Integer
        Dim TempByte(0 To 0) As Byte
        Do While i < IncomingString.Length
            If IncomingString.Substring(i, 1) = "=" Then
                TempString = IncomingString.Substring(i + 1, 2)
                TempInteger = Integer.Parse(TempString, System.Globalization.NumberStyles.HexNumber)
                TempByte(0) = System.Convert.ToByte(TempInteger)
                ReturnString &= System.Text.Encoding.GetEncoding(CodePage).GetString(TempByte, 0, 1)
                i += 3
            Else
                ReturnString &= IncomingString.Substring(i, 1)
                i += 1
            End If
        Loop
        Return ReturnString
    End Function



Эта функция служит для декодирования Base64
Код: Выделить всё
    Private Function ConvertBase64Coding(ByRef IncomingString As String, ByRef CodePage As String) As String
        Dim b() As Byte
        b = System.Convert.FromBase64String(IncomingString)
        Dim returnString As String = System.Text.Encoding.GetEncoding(CodePage).GetString(b)
        Return returnString
    End Function
Изображение


Вернуться в Visual Basic .NET

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 120

    TopList