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

Опубликовал Тарас Гулеватый (Foxx) в раздел Программирование - Практика программирования

Иногда бывает нужно декодировать строку вида "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
22
.epf 7,02Kb 22 Скачать

См. также

Добавить вознаграждение
Комментарии
1. Яков Коган (Yashazz) 1940 12.12.11 01:03 Сейчас в теме
А ещё есть такая штука, regexp называется.
2. Тарас Гулеватый (Foxx) 86 12.12.11 05:14 Сейчас в теме
(1) Yashazz, представьте себе, я в курсе)
Но в данном случае она здесь не помощник.
3. Трактор Трактор (Трактор) 1107 14.12.11 10:09 Сейчас в теме
4. Тарас Гулеватый (Foxx) 86 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) 86 19.06.12 11:47 Сейчас в теме
(6) Murom, рад, что помогло))
Про кодирование строки в обе стороны - такая задача в данной статье не ставилась, т.к. на инфостарте уже существуют публикации для обратного преобразования. См. например, ссылку в (3)
8. Роман (Windsor77) 8 31.01.13 12:24 Сейчас в теме
9. Илья Фамилия (Murom) 31.01.13 12:33 Сейчас в теме
(8) Windsor77,
Спасибо, посмотрю.
А так уже сам написал и забыл.
Где-то в парсере JSON крутиться. Пока без проблем.