
Функции urldecode и urlencode на Ассемблере

Функции urldecode и urlencode на Ассемблере
Моя реализация функций PHP urldecode и urlencode, а также двух их разновидностей rawurldecode и rawurlencode на Ассемблере. Алгоритм их работы описан в документации. Единственное отличие от оригинальной функции rawurlencode в том, что кодируется вся строка целиком, а не только буквенно-цифровые символы. На мой взгляд, это более логичное поведение функции с приставкой "raw". В остальном никаких отличий нет.
Начну с функции декодирования, как с более востребованной. У нее четыре параметра: указатель на исходную строку, длина закодированной строки, указатель на буфер для раскодированной строки и флаг - использовать или нет RAW-декодирование. Разница RAW-декодирования от обычного заключается только в том, что при обычном декодировании символ "+" заменяется на пробел, а при RAW-декодировании обрабатываются только скаляры.
Code (Assembler) : Убрать нумерацию
- ;-----------------------------------------------------------------------
- ; Функция URL-декодирования
- ; by ManHunter / PCL
- ; http://www.manhunter.ru
- ;-----------------------------------------------------------------------
- ; Параметры:
- ; lpData - указатель на строку
- ; dSize - длина строки
- ; lpBuff - указатель на буфер-приемник
- ; dRaw - использовать RAW-декодирование (TRUE/FALSE)
- ;-----------------------------------------------------------------------
- proc url_decode lpData:DWORD, dSize:DWORD, lpBuff:DWORD, dRaw:DWORD
- push eax ebx ecx edx edi esi
- mov ecx,[dSize]
- mov esi,[lpData]
- mov edi,[lpBuff]
- or ecx,ecx
- jz .loc_done
- .loc_decode:
- xor eax,eax
- lodsb
- ; Принудительно конвертировать все подряд
- cmp [dRaw],TRUE
- je .raw_decode
- ; '+' заменяется на пробел
- cmp al,'+'
- jne .raw_decode
- mov al,' '
- jmp .loc_store
- .raw_decode:
- ; Возможно, это закодированный символ
- cmp al,'%'
- jne .loc_store
- ; Строка заканчивается?
- cmp ecx,3
- jb .loc_store
- cmp byte [esi],'u'
- jne .decode_ascii
- ; Строка заканчивается?
- cmp ecx,5
- jb .loc_store
- ; Двухбайтные юникод-скаляры %uNNNN (UTF-16)
- .decode_unicode:
- push eax
- xor ebx,ebx
- xor edx,edx
- inc edx
- mov ah,5
- jmp .decode_digit
- ; Однобайтовые скаляры %NN
- .decode_ascii:
- push eax
- xor ebx,ebx
- xor edx,edx
- mov ah,2
- ; Декодировать нужное количество цифр
- .decode_digit:
- shl ebx,4
- mov al,byte [esi+edx]
- cmp al,'0'
- jb .loc_skip
- cmp al,'9'
- ja @f
- sub al,'0'
- jmp .decode_digit_next
- @@:
- ; Символ в нижний регистр
- or al,20h
- cmp al,'a'
- jb .loc_skip
- cmp al,'f'
- ja .loc_skip
- sub al,'a'-10
- .decode_digit_next:
- add bl,al
- inc edx
- cmp dl,ah
- jb .decode_digit
- xchg eax,ebx
- shr ebx,8
- ; Пропустить следующие символы
- sub ecx,ebx
- add esi,ebx
- pop ebx
- jmp .loc_store
- .loc_skip:
- pop eax
- .loc_store:
- cmp eax,0FFh
- jbe .loc_store_byte
- .loc_store_word:
- ; Записать раскодированный юникодный символ в строку
- stosw
- jmp @f
- .loc_store_byte:
- ; Записать раскодированный символ в строку
- stosb
- @@:
- loop .loc_decode
- .loc_done:
- ; Символ конца строки
- mov al,0
- stosb
- pop esi edi edx ecx ebx eax
- ret
- endp
Функция кодирования также принимает четыре параметра: указатель на исходную строку, длина строки, указатель на буфер для закодированной строки и флаг - использовать или нет RAW-кодирование. В обычном режиме режим замены символов в функции аналогичен PHP-функции, в режиме RAW-кодирования обрабатываются все символы строки без исключения.
Code (Assembler) : Убрать нумерацию
- ;-----------------------------------------------------------------------
- ; Функция URL-кодирования
- ; by ManHunter / PCL
- ; http://www.manhunter.ru
- ;-----------------------------------------------------------------------
- ; Параметры:
- ; lpData - указатель на строку
- ; dSize - длина строки
- ; lpBuff - указатель на буфер-приемник
- ; dRaw - использовать RAW-кодирование (TRUE/FALSE)
- ;-----------------------------------------------------------------------
- proc url_encode lpData:DWORD, dSize:DWORD, lpBuff:DWORD, dRaw:DWORD
- push eax ecx edi esi
- mov ecx,[dSize]
- mov esi,[lpData]
- mov edi,[lpBuff]
- or ecx,ecx
- jz .loc_done
- .loc_encode:
- lodsb
- ; Принудительно конвертировать все подряд
- cmp [dRaw],TRUE
- je .raw_encode
- ; Пробел заменяется на '+'
- cmp al,' '
- jne @f
- mov al,'+'
- jmp .loc_store
- @@:
- ; Следующие символы без изменения
- cmp al,'_'
- jz .loc_store
- cmp al,'.'
- jz .loc_store
- cmp al,'-'
- jz .loc_store
- ; Буквенно-цифровые символы без изменения
- cmp al,'0'
- jb .raw_encode
- cmp al,'9'
- jbe .loc_store
- cmp al,'A'
- jb .raw_encode
- cmp al,'Z'
- jbe .loc_store
- cmp al,'a'
- jb .raw_encode
- cmp al,'z'
- jbe .loc_store
- ; Все остальное кодируется
- .raw_encode:
- push eax
- mov al,'%'
- stosb
- pop eax
- ; Перевести байт в 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
- .loc_store:
- ; Записать закодированный символ в строку
- stosb
- loop .loc_encode
- .loc_done:
- ; Символ конца строки
- mov al,0
- stosb
- pop esi edi ecx eax
- ret
- endp
В приложении примеры двух программ с исходными текстами, демонстрирующие функции URL-кодирования и декодирования текстовых строк.
Просмотров: 5472 | Комментариев: 0
Метки: Assembler, полезные функции

Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
Комментариeв нет

Добавить комментарий
Заполните форму для добавления комментария
