Декодирование URL

Программирование - Практика программирования

Иногда бывает нужно декодировать строку вида "c:\documents%20and%20settings\" в удобочитаемый текст. Можно, конечно, заменить все "%20" на пробелы, и считать что задача решена. А если в строке закодированы подобным образом не только пробелы? Если на входе попался URL с кучей подобных "процентов"?

Данная функция сделает правильное декодирование подобной строки.

Кому интересна теория - см. RFC 2396 часть 2

Собственно код:

Функция Из16ВЧисло(Знач Значение)

   
Результат = 0;
   
Множитель = 1;
    Пока
Значение <> "" Цикл
       
Результат = Результат + Множитель * (Найти("0123456789ABCDEF", Прав(Значение,1))-1);
       
Множитель = Множитель * 16;
       
Значение = Лев(Значение,СтрДлина(Значение)-1);
    КонецЦикла;
    Возврат
Результат;

КонецФункции

Функция
ДекодироватьURL(URL, WindowsFileURI=Истина)

   
ДлинаСтроки = СтрДлина(URL);
   
Инд = 1;
   
Результат = "";
   
ПолныйКод = 0;
   
ОсталосьСимволов = 0;

    Пока
Инд <= ДлинаСтроки Цикл

       
Код = КодСимвола(URL, Инд);

        Если
Код = 37 Тогда
           
// Символ(37) = "%"
           
Код = Из16ВЧисло(Сред(URL, Инд+1, 2));
           
Инд = Инд + 2;
        ИначеЕсли
ОсталосьСимволов = 0 Тогда
            Если (
Код = 43) и (не WindowsFileURI) Тогда
               
// Символ(43) = "+"
               
Код = 32; // Символ(32) = " " (пробел)
           
КонецЕсли;
           
Результат = Результат + Символ(Код);
           
Инд = Инд + 1;
            Продолжить;
        КонецЕсли;

        Если
Код <= 127 Тогда
           
// Код = 0b0ххххххх
           
Результат = Результат + Символ(Код);
        ИначеЕсли
Код <= 191 Тогда
           
// Код = 0b10хххххх
           
ПолныйКод = (ПолныйКод*64) + (Код%64); // shl(ПолныйКод, 6) + (Код & 0x3F)
           
ОсталосьСимволов = ОсталосьСимволов - 1;
            Если
ОсталосьСимволов = 0 Тогда
               
Результат = Результат + Символ(ПолныйКод);
            КонецЕсли;
        ИначеЕсли
Код <= 223 Тогда
           
// Код = 0b110ххххх
           
ПолныйКод = Код % 32; // Код & 0x1F
           
ОсталосьСимволов = 1;
        ИначеЕсли
Код <= 239 Тогда
           
// Код = 0b1110хххх
           
ПолныйКод = Код % 16; // Код & 0x0F
           
ОсталосьСимволов = 2;
        ИначеЕсли
Код <= 247 Тогда
           
// Код = 0b11110ххх
           
ПолныйКод = Код % 8; // Код & 0x07
           
ОсталосьСимволов = 3;
        ИначеЕсли
Код <= 251 Тогда
           
// Код = 0b111110хх
           
ПолныйКод = Код % 4; // Код & 0x03
           
ОсталосьСимволов = 4;
        ИначеЕсли
Код <= 253 Тогда
           
// Код = 0b1111110х
           
ПолныйКод = Код % 2; // Код & 0x01
           
ОсталосьСимволов = 5;
        КонецЕсли;

       
Инд = Инд + 1;
    КонецЦикла;

    Возврат
Результат;
КонецФункции

Примеры:

URL = ДекодироватьURL("http://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80");
// URL = "http://ru.wikipedia.org/wiki/Пример"

URL = ДекодироватьURL("c:\documents%20and%20settings\");
// URL = "c:\documents and settings\"

Вот и все)

PS. Очень жаль, что 1С в платформе 8.х до сих пор не реализовала битовых операций. Поэтому реализация данной функции не столь изящна, как могла бы быть.

 

Updated 10.12.11: Исправлена ошибка при декодировании URI в протоколе file:// в Windows. Добавлен второй параметр в функции WindowsFileURI - признак того, что декодируется именно такая строка. При значении этого параметра Ложь - обработка как для "обычных" :) интеренет протоколов.

Скачать файлы

Наименование Файл Версия Размер
Пример
.epf 7,02Kb
10.12.11
23
.epf 7,02Kb 23 Скачать

См. также

Вознаграждение за ответ
Показать полностью
Комментарии
1. Яков Коган (Yashazz) 2080 12.12.11 01:03 Сейчас в теме
А ещё есть такая штука, regexp называется.
2. Тарас Гулеватый (Foxx) 90 12.12.11 05:14 Сейчас в теме
(1) Yashazz, представьте себе, я в курсе)
Но в данном случае она здесь не помощник.
3. Трактор Трактор (Трактор) 1136 14.12.11 10:09 Сейчас в теме
4. Тарас Гулеватый (Foxx) 90 14.12.11 11:08 Сейчас в теме
Трактор пишет:

Такая публикация уже есть http://infostart.ru/public/70330/

Не совсем так. Указанная публикация выполняет преобразование в обратную сторону :). Т.е. из "Микроскоп" в "%D0%9C%D0%B8%D0%BA%D1%80%D0%BE%D1%81%D0%BA%D0%BE%D0%BF".

А у меня - из "%D0%9C%D0%B8%D0%BA%D1%80%D0%BE%D1%81%D0%BA%D0%BE%D0%BF" в "Микроскоп" :)
Трактор; +1 Ответить
5. Maksim Titov (Maks_Payn) 17.12.11 13:46 Сейчас в теме
Очень интересно и позновательно! Спасибо! ))
6. Илья Фамилия (Murom) 18.06.12 14:20 Сейчас в теме
Спасибо ,помогло.
Как раз собрал для модуль для преобразования в код URL и обратно.
Было бы удобно ,если б в статье была не только процедура декодирования ,но и преобразования в код URL.
7. Тарас Гулеватый (Foxx) 90 19.06.12 11:47 Сейчас в теме
(6) Murom, рад, что помогло))
Про кодирование строки в обе стороны - такая задача в данной статье не ставилась, т.к. на инфостарте уже существуют публикации для обратного преобразования. См. например, ссылку в (3)
8. Роман (Windsor77) 10 31.01.13 12:24 Сейчас в теме
9. Илья Фамилия (Murom) 31.01.13 12:33 Сейчас в теме
(8) Windsor77,
Спасибо, посмотрю.
А так уже сам написал и забыл.
Где-то в парсере JSON крутиться. Пока без проблем.
10. Юрий Н (graphbuh) 141 30.01.17 18:31 Сейчас в теме
Интересно, почему это не работает для запросов яндекса. За пример плюс.
11. Тарас Гулеватый (Foxx) 90 31.01.17 10:17 Сейчас в теме
(10) а что не так с запросами яндекса? Можно пример?
12. Юрий Н (graphbuh) 141 31.01.17 12:36 Сейчас в теме
Пожалуйста, Тарас.
допустим здесь я пишу поиск - "веселые картинки" в форме поиск яндекса
http://www.proza.ru/search.html
после этого открывается страница запроса с текстом
http://www.proza.ru/cgi-bin/search.pl?text=%E2%E5%F1%E5%EB%FB%E5+%EA%E0%F0%F2%E8%ED%EA%E8&searchid­=126972&l10n=ru&web=0#1073
т.е. кусок %E2%E5%F1%E5%EB%FB%E5+%EA%E0%F0%F2%E8%ED%EA%E8 это закодированная кириллица.
получаю

http://www.proza.ru/cgi-bin/search.pl?text=+&searchid=126972&l10n=ru&web=0#1073
13. Тарас Гулеватый (Foxx) 90 31.01.17 16:56 Сейчас в теме
(12) там они изобрели свой собственный способ кодирования).

У них там строка закодирована в кодировке Windows-1251 (судя по внешнему виду, не проверял)
А моя функция декодирует UTF-8

"веселые картинки" по-правильному URL-кодированию будет
%D0%B2%D0%B5%D1%81%D0%B5%D0%BB%D1%8B%D0%B5%20%D0%BA%D0%B0%D1­%80%D1%82%D0%B8%D0%BD%D0%BA%D0%B8

14. Юрий Н (graphbuh) 141 01.02.17 09:20 Сейчас в теме
Спасибо за информацию, Тарас. Вчера вечером прочитал, что начиная с некоторого момента они применяют шифрование (
Оставьте свое сообщение