Работа с Quoted-Printable строками на Ассемблере
Механизм конвертации Quoted-Printable предназначен для представления данных, в основном состоящих из байтов, соответствующих символам, имеющим изображение в символьном наборе ASCII. Если конвертируемые данные в основном представляют собой ASCII-текст, то конечная их форма остается узнаваемой и читаемой для человека. Как правило, такое кодирование используется при передаче бинарных данных или текстов в различных кодировках через электронную почту. Сообщение, полностью состоящее из ASCII-символов, также может быть конвертировано в Quoted-Printable, что гарантирует его содержимому целостность при прохождении через всякие шлюзы, в которых происходит языковая перекодировка символов или преобразование концов строк и т.д. В результате данного кодирования все байты сообщения будут иметь такие значения, которые в дальнейшем не будут модифицированы почтовым транспортом.Согласно спецификации, в Quoted-Printable байты должны быть представлены в соответствии со следующими правилами:
- Каждый байт, кроме тех, которые используются для обозначения конца строки, может быть представлен с помощью двух шестнадцатеричных цифр, предваряемых знаком "=". При написании шестнадцатеричных цифр с A по F должны использоваться заглавные буквы. Кроме тех случаев, когда нижеследующие правила позволяют альтернативное кодирование, данное правило является обязательным.
- Байты с десятичным значением с 33 по 60 и с 62 по 126 МОГУТ быть представлены ASCII-символами, соответствующими этим значениям (с '!' по '<' и с '>' по '~').
- Пробел в кодированной строке может быть заменен на символ подчеркивания "_".
- Байты со значениями 9 и 32 МОГУТ быть представлены как ASCII-символы "Табуляция" и "Пробел", но НЕ ДОЛЖНЫ быть представлены так в конце строки. Везде, где они представлены соответствующими ASCII-символами, за ними должен следовать символ, имеющий графическое изображение (печатный символ). В конце же строки символы табуляции и пробела должны быть представлены в соответствии с правилом #1, так как некоторые почтовые транспорты могут убирать пробелы в конце строки.
- Конец строки в тексте письма должен быть представлен (в соответствии с RFC 822) последовательностью CRLF. Так как в каноническом представлении текста не требуется визуального отображения символов конца строки, в Quoted-Printable не используется видимых символов для обозначения конца строки.
- В соответствии со спецификацией Quoted-Printable, длина строки не должна превышать 76 символов. В противном случае используется "мягкий" перевод строки, представимый знаком равенства. Например, если исходная строка имела вид:
Если программист в девять утра уже на работе, значит он там же и ночевал.
то в Quoted-Printable encoding он может быть представлена следующим образом:
Если программист в девять утра =
уже на работе, значит =
он там же и ночевал.
Это обеспечивает механизм восстановления исходной длины строки пользовательским почтовым агентом.
Функция Quoted-Printable-декодирования принимает в качестве параметров три значения: указатель на исходную строку, длина исходной строки и указатель на буфер-приемник для раскодированной строки.
Code (Assembler) : Убрать нумерацию
- ;-----------------------------------------------------------------------
- ; Функция Quoted-Printable-декодирования
- ; by ManHunter / PCL
- ; http://www.manhunter.ru
- ;-----------------------------------------------------------------------
- ; Параметры:
- ; lpData - указатель на строку
- ; dSize - длина строки
- ; lpBuff - указатель на буфер-приемник
- ;-----------------------------------------------------------------------
- proc qp_decode lpData:DWORD, dSize:DWORD, lpBuff:DWORD
- push eax ebx ecx edi esi
- mov ecx,[dSize]
- mov esi,[lpData]
- mov edi,[lpBuff]
- or ecx,ecx
- jz .loc_done
- .loc_decode:
- lodsb
- ; Замена символа подчеркивания на пробел
- ; для поддержки стандартам QP-кодирования
- cmp al,'_'
- jne @f
- mov al,' '
- jmp .loc_store
- @@:
- ; Возможно, это закодированный символ
- cmp al,'='
- jne .loc_store
- ; Строка заканчивается?
- cmp ecx,3
- jb .loc_store
- ; Мягкий перенос строки?
- cmp word [esi],0A0Dh
- jne .first_digit
- inc esi
- inc esi
- dec ecx
- dec ecx
- jmp .loc_loop
- ; Проверить два следующих символа
- .first_digit:
- ; Первый символ за '='
- mov bl,byte [esi]
- cmp bl,'0'
- jb .loc_store
- cmp bl,'9'
- ja @f
- sub bl,'0'
- shl bl,4
- jmp .second_digit
- @@:
- ; Символ в нижний регистр
- or bl,20h
- cmp bl,'a'
- jb .loc_store
- cmp bl,'f'
- ja .loc_store
- sub bl,'a'-10
- shl bl,4
- .second_digit:
- ; Второй символ за '='
- mov bh,byte [esi+1]
- cmp bh,'0'
- jb .loc_store
- cmp bh,'9'
- ja @f
- sub bh,'0'
- jmp .loc_make_byte
- @@:
- ; Символ в нижний регистр
- or bh,20h
- cmp bh,'a'
- jb .loc_store
- cmp bh,'f'
- ja .loc_store
- sub bh,'a'-10
- .loc_make_byte:
- ; Собрать байт из двух половинок
- add bl,bh
- mov al,bl
- ; Пропустить следующие символы
- dec ecx
- dec ecx
- inc esi
- inc esi
- .loc_store:
- ; Записать раскодированный символ в строку
- stosb
- .loc_loop:
- loop .loc_decode
- .loc_done:
- ; Символ конца строки
- mov al,0
- stosb
- pop esi edi ecx ebx eax
- ret
- endp
Функция кодирования Quoted-Printable принимает четыре параметра: указатель на исходную строку, длина исходной строки, указатель на буфер-приемник для закодированной строки и максимальная длина строки, после которой будет записываться символ мягкого переноса. Если мягкие переносы использовать не требуется, этот параметр должен быть равен -1.
Code (Assembler) : Убрать нумерацию
- ;-----------------------------------------------------------------------
- ; Функция Quoted-Printable-кодирования
- ; by ManHunter / PCL
- ; http://www.manhunter.ru
- ;-----------------------------------------------------------------------
- ; Параметры:
- ; lpData - указатель на строку
- ; dSize - длина строки
- ; lpBuff - указатель на буфер-приемник
- ; dLen - длина строки для мягкого переноса (рекомендуется 76
- ; символов), -1 = без лимита
- ;-----------------------------------------------------------------------
- proc qp_encode lpData:DWORD, dSize:DWORD, lpBuff:DWORD, dLen:DWORD
- push eax ecx edi esi
- mov ecx,[dSize]
- mov esi,[lpData]
- mov edi,[lpBuff]
- ; Проверка и корректировка длины
- cmp [dLen],-1
- jne @f
- sub [dLen],3
- cmp [dLen],3
- ja @f
- mov [dLen],3
- @@:
- or ecx,ecx
- jz .loc_done
- xor ebx,ebx
- .loc_encode:
- mov al,'='
- stosb
- lodsb
- ; Перевести байт в HEX-строку
- movzx eax,al
- ror eax,4
- and al,0Fh
- daa
- add al,0F0h
- adc al,40h
- stosb
- shr eax,28
- and al,0Fh
- daa
- add al,0F0h
- adc al,40h
- stosb
- ; Требуется ли мягкий перенос?
- add ebx,3
- cmp ebx,[dLen]
- jb @f
- xor ebx,ebx
- mov al,'='
- stosb
- mov eax,0A0Dh
- stosw
- @@:
- loop .loc_encode
- .loc_done:
- ; Символ конца строки
- mov al,0
- stosb
- pop esi edi ecx eax
- ret
- endp
В приложении примеры двух программ с исходными текстами, демонстрирующие функции Quoted-Printable кодирования и декодирования текстовых строк.
Просмотров: 4183 | Комментариев: 1
Метки: Assembler, полезные функции
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
ManHunter
(28.12.2015 в 21:25):
В функции декодирования добавил замену подчеркивания "_" на пробел, т.к. подобная замена используется в почтовых программах. Код прокомментирован, если такую замену делать не надо, то удалите его из исходника.
Добавить комментарий
Заполните форму для добавления комментария