Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2009.10.11;
Скачать: [xml.tar.bz2];

Вниз

URL-кодировка (URL encoding, Percent-encoding)   Найти похожие ветки 

 
TIF ©   (2009-07-28 15:51) [0]

Меня заело :-( Не могу никак понять одну вещь
Программа получает из браузера ссылку. Всё бы хорошо, но только IE (люблю Microsoft :) передаёт ссылку "как есть", остальные браузеры применяют к ней URL-кодирование. Опять же, всё бы хорошо, но! Firefox кодирует каждый символ двумя байтами, Opera  и Chrome - одним:

IE
[AbCdEfАбВгДе]
Opera
[AbCdEf%C0%E1%C2%E3%C4%E5]
Chrome
%5BAbCdEf%C0%E1%C2%E3%C4%E5%5D
Fx
[AbCdEf%D0%90%D0%B1%D0%92%D0%B3%D0%94%D0%B5]


А теперь и вопрос, на котором меня заело: как определить, что %D0%90 - это именно ОДИН символ, а не два? %-\

PS: возможности определить, какой браузер передал ссылку нет


 
Lamer@fools.ua ©   (2009-07-28 15:55) [1]

В заголовке запроса кодировка УРЛа должна передаваться, вроде...


 
TIF ©   (2009-07-28 15:57) [2]

> В заголовке запроса

Нет никакого заголовка. В наличии только ссылка...


 
clickmaker ©   (2009-07-28 16:07) [3]

> Программа получает из браузера ссылку

из адресной строки? IE 7 на английской винде кодирует так: AbCdEf%c0%e1%c2%e3%c4%e5


 
Anatoly Podgoretsky ©   (2009-07-28 16:07) [4]

Тогда ни как, кроме методом проб и ошибок. Но зато вариантов всего лишь два.

И предположение насчет браузеров, кто как кодирует в принципе неверное.


 
TIF ©   (2009-07-28 16:18) [5]

> из адресной строки?

Нет. Pluggable protocol

> Anatoly Podgoretsky ©   (28.07.09 16:07) [4]
> Тогда никак, кроме методом проб и ошибок

Ну есть конечно вариант, внедрить в ссылку в заранее определенное место пару буковок и анализировать их, но хочется простое решение, должно же оно быть...
У меня мысли крутятся вокруг UTF-8:
Текст, состоящий только из символов с номером меньше 128, при записи в UTF-8 превращается в обычный текст ASCII. И наоборот, в тексте UTF-8 любой байт со значением меньше 128 изображает символ ASCII с тем же кодом.
Тут похожая ситуация. Только провести параллели бы какие-то...


 
Anatoly Podgoretsky ©   (2009-07-28 16:52) [6]

Никаких паралелей, один и тот же текст "AbCdEf%D0%90" может быть как OEM, так и ANSI, так и UTF-8


 
clickmaker ©   (2009-07-28 16:59) [7]

а программа на дельфи?
я бы погуглил по словам UrlDecode Delphi


 
Anatoly Podgoretsky ©   (2009-07-28 17:01) [8]

> clickmaker  (28.07.2009 16:59:07)  [7]

Без знания кодировки это мало чем поможет.


 
antonn ©   (2009-07-28 17:02) [9]


> Никаких паралелей, один и тот же текст "AbCdEf%D0%90" может
> быть как OEM, так и ANSI, так и UTF-8

AbCdEf%D0%90 только в UTF читаем как обычный текст.


> TIF ©   (28.07.09 15:51)

ищи %D0 и смотри парные ему, он в UTF есть


 
Noctis   (2009-07-28 17:08) [10]

Строку, требующую раскодирования можно отличить от строки, не требующей раскодирования наличием в ней паттерна, удовлетворяющего регулярному выражению %\w{2}.
После преобразования последовательностей кодов в байты наличие UTF-8 с большой вероятностью можно определить соответствием последовательностей байтов в строке следующим паттернам (см. RFC utf-8).

  Char. number range  |        UTF-8 octet sequence
     (hexadecimal)    |              (binary)
  --------------------+---------------------------------------------
  0000 0000-0000 007F | 0xxxxxxx
  0000 0080-0000 07FF | 110xxxxx 10xxxxxx
  0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
  0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx


 
TIF ©   (2009-07-28 17:35) [11]

> я бы погуглил по словам UrlDecode Delphi

Уже скачал несколько URLEncode и URLDecode функций, но самое весёлое, что они не работают в D2009 (дополнительные проблемы с кодировкой лезут)...


 
Anatoly Podgoretsky ©   (2009-07-28 19:02) [12]


> AbCdEf%D0%90 только в UTF читаем как обычный текст.

Он отлично читается - это русская буква Р и вторая казахская буква, как известно у казахов таже кодовая страницы, только расширеная. Кроме того я взял первую попавшию последовательность, можно взять и другую.


 
Anatoly Podgoretsky ©   (2009-07-28 19:05) [13]


> Уже скачал несколько URLEncode и URLDecode функций, но самое
> весёлое, что они не работают в D2009 (дополнительные проблемы
> с кодировкой

Ты зря это делал, string в 2009 UnicodeString, а не AnsiString.
Надо использовать из 2009 или особый формат вызова и определение переменных.
Одна из ошибок Д2009 - это то что они перестарались с переводом на UnicodeString, перевели больше чем надо, пострадали Indy и IB, и наверно еще ряд сетевых функций.


 
Пит   (2009-07-29 13:30) [14]

Я уже поднимал ветку по этому поводу.

Да, это URL кодирование (через проценты), в одном случае кодируеся win-1251, в другом случае unicode (поэтому два байта на символ).

В общем случае определить невозможно формат. Но есть способы догадаться. Даже в windows API вроде есть встроенная функция, которая с определенной вероятностью пытается определить набор символов, ANSI или Wide. Не помню как называется, в Рихтере есть.

Например, Гугл это делает достаточно хорошо. Кодировки разные:

- win-1251
http://www.google.ru/search?hl=ru&q=%EF%F0%E8%E2%E5%F2

- unicode
http://www.google.ru/search?hl=ru&q=%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82

а результат одинаковый.


 
clickmaker ©   (2009-07-29 13:39) [15]

> в windows API вроде есть встроенная функция

IsTextUnicode


 
Anatoly Podgoretsky ©   (2009-07-29 13:40) [16]

> Пит  (29.07.2009 13:30:14)  [14]

Попробуй изменить %D0%BF на %D0%01 и посмотри на результат
Гугл обладает излишней информацией и плюс проверяет по словарю.


 
Anatoly Podgoretsky ©   (2009-07-29 13:44) [17]

Заодно можешь провести тоже и для ANSI может даже нагляднее будет.


 
Пит   (2009-07-29 17:56) [18]

А к чему вы это говорите? Тон как будто опровергаете, а смысл как будто подтверждаете.

Естественно, это косвенные методы определения, точно также как и у IsTextUnicode. Ясно было сказано:

>В общем случае определить невозможно формат


 
blackman ©   (2009-07-29 20:06) [19]

См.<meta http-equiv="Content-Type" content="text/html; charset... - страницы
См. функции
Unit: IdGlobal
URLDecode(AnsiToUtf8("привет")) //"%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82"
URLDecode("привет") //"%CF%F0%E8%E2%E5%F2%2E"

или HTTPEncode(AnsiToUtf8(...

function HTTPEncode(const AStr: string): string;
const
  NoConversion = ["A".."Z", "a".."z", "*", "@", ".", "_", "-"];
var
  Sp, Rp: PChar;
begin
  SetLength(Result, Length(AStr) * 3);
  Sp := PChar(AStr);
  Rp := PChar(Result);
  while Sp^ <> #0 do
  begin
    if Sp^ in NoConversion then
      Rp^ := Sp^
    else if Sp^ = " " then
      Rp^ := "+"
    else
    begin
      FormatBuf(Rp^, 3, "%%%.2x", 6, [Ord(Sp^)]);
      Inc(Rp, 2);
    end;
    Inc(Rp);
    Inc(Sp);
  end;
  SetLength(Result, Rp - PChar(Result));
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Edit1.Text := HTTPEncode(Edit1.Text);
end;
http://www.swissdelphicenter.ch/

Кроме того на этом сайте тоже кое что есть
http://www.delphimaster.ru/books/978594723593/fragment.html


 
Piter ©   (2009-07-29 22:24) [20]

blackman ©   (29.07.09 20:06) [19]

по-моему, ты нифига не въехал в квалификацию автора вопроса и в то, что он собственно хочет.

Вопрос не в том, откуда это взялось, с самого начала вроде автор дал понять, что он прекрасно понимает, что есть ANSI, а есть unicode.

Вопрос в том, как определить по известному GET-параметру в какой кодировке представлены данные. И ответ не раз дан опять же в этой ветке - никак. Можно только предполагать с той или иной точностью.


 
Anatoly Podgoretsky ©   (2009-07-29 23:01) [21]

> Piter  (29.07.2009 22:24:20)  [20]

При том определить не с помощью Гугловеба, а автономно, Гугловеб вносит искажения в процесс определения, поскольку добавляется информация о локальной кодировке компьютера. Наиболее качественное решение в [10] вероятность будет высокая и пропорциональна длине ссылке. Надо только учесть, что не все символы в диапазоне 00-7F выводятся указаным кодом, по правилам на URI их тоже надо экранировать, но уже однобайтным кодом. Список этих кодов также есть в RFC и также особенность вывода пробелов, они заменяются по другой схеме.

Короче за эти годы очень намудрили. Из приведеных, только Chrome соответствует RFC для ANSI и наверно он также правильно работает с UTF. Кроме того тут еще отсутствует вариант с Unicode - %u####


 
TIF ©   (2009-07-30 00:04) [22]

> Piter ©   (29.07.09 22:24) [20]
> blackman ©   (29.07.09 20:06) [19]по-моему, ты нифига не
> въехал в квалификацию автора вопроса и в то, что он собственно
> хочет.

+1 :)

Anatoly Podgoretsky ©   (29.07.09 23:01) [21]
> Наиболее качественное решение в [10] вероятность будет высокая
> и пропорциональна длине ссылке.

Наверное в скором времени доведу до ума это распознавание, хоть оно и не идеальное, но пока всё-таки решил не мучаться и внедрять в начало ссылки короткое слово кириллицей (какой-нибудь маленький предлог, чтоб хоть со смыслом смотрелся, что-то вроде "Open?Для=http://") и ориентироваться по нему

> Из приведеных, только Chrome соответствует RFC для ANSI


Ох, не знаю. Покопался с хромом - вообще какой-то извращённый браузер :-( Создан на движке WebKit, но содержит куча странных отличий от Safari. Сафари, например, не приводит ссылку к нижнему регистру, а Chrome приводит, Сафари [ и ] в %-кодировку не переводит, а Chromt переводит

Сколько браузеров - столько и проблем :) Что и требовалось доказать


 
Anatoly Podgoretsky ©   (2009-07-30 09:38) [23]

> TIF  (30.07.2009 00:04:22)  [22]

Я не знаю, насколько извращен, я просто вижу по приведеным ссылкам


 
Anatoly Podgoretsky ©   (2009-07-30 09:42) [24]

> TIF  (30.07.2009 00:04:22)  [22]

> Ох, не знаю. Покопался с хромом - вообще какой-то извращённый браузер :-( Создан на движке WebKit, но содержит куча странных отличий от Safari. Сафари, например, не приводит ссылку к нижнему регистру, а Chrome приводит, Сафари [ и ] в %-кодировку не переводит, а Chromt переводит

Приведение к нижнему регистру, идиотичние не придумать, это же полный капец. Наверно у них там в Гугле все в нижнем регистре, вот и думают, что у других также.

ЗЫ: как на самом деле я не знаю.

Кстати я бы не стал делать вывод, насчет ИЕ, что мол он посылает как есть, этот браузер много хитрее.


 
TIF ©   (2009-08-06 20:18) [25]

> как определить, что %D0%90 - это именно ОДИН символ, а не
> два?

Отлично :) С поставленной задачей я всё-таки справился, даже добился большего, чем хотел.

В результате мучений и размышлений родилась функция URLDecode. На входе - строка в однобайтной или многобайтной (2-4 байта) URL-кодировке, на выходе - расшифрованный текст

Хотя я на это и не рассчитывал, но если этой функции скормить мешанину (один символ зашифрован с использованием одного байта на символ, а другой - двумя, тремя, а то и четырьмя), то на выходе также получаем расшифрованный текст!
Здесь всё благодаря "UTF-8 octet sequence (binary)" из RFC для UTF-8, то что давалось Noctis-ом в [10]:
> После преобразования последовательностей кодов в байты наличие
> UTF-8 с большой вероятностью можно определить соответствием
> последовательностей байтов в строке следующим паттернам
> (см. RFC utf-8).

Только работает это и без вычисления вероятностей. А вот у поисковиков не работает :) Яндекс с Google преобразуют мешашину "жёстко", а Bing просто игнорирует "однобайтные символы" с кодами > 128

http://yandex.ru/yandsearch?text=%EE%EF%F6%E8%E8+%D0%BE%D0%BF%D1%86%D0%B8%D0%B8%E2%82%AC
http://www.google.com/search?q=%EE%EF%F6%E8%E8+%D0%BE%D0%BF%D1%86%D0%B8%D0%B8%E2%82%AC
http://www.bing.com/search?q=%EE%EF%F6%E8%E8+%D0%BE%D0%BF%D1%86%D0%B8%D0%B8%E2%82%AC

Для полной уверенности прогнал функцию ещё по нескольким тестам, она их прошла успешно:
AbCdEf%D0%90%E2%82%AC

%EE%EF%F6%E8%E8%E2%82%AC
%D0%BE%D0%BF%D1%86%D0%B8%D0%B8%E2%82%AC
%EE%EF%F6%E8%E8+%D0%BE%D0%BF%D1%86%D0%B8%D0%B8%E2%82%AC
%D0%BE%D0%BF%D1%86%D0%B8%D0%B8+%EE%EF%F6%E8%E8%E2%82%AC

%d2%e5%f1%f2%ee%e2%e0%ff%20%f1%f1%fb%eb%ea%e0
%d0%a2%d0%b5%d1%81%d1%82%d0%be%d0%b2%d0%b0%d1%8f%20%d1%81%d1%81%d1%8b%d0%bb%d0%ba%d0%b0
%d2%e5%f1%f2%ee%e2%e0%ff%20%f1%f1%fb%eb%ea%e0+%d0%a2%d0%b5%d1%81%d1%82%d0%be%d0%b2%d0%b0%d1%8f%20%d1%81%d1%81%d1%8b%d0%bb%d0%ba%d0%b0
%d0%a2%d0%b5%d1%81%d1%82%d0%be%d0%b2%d0%b0%d1%8f%20%d1%81%d1%81%d1%8b%d0%bb%d0%ba%d0%b0+%d2%e5%f1%f2%ee%e2%e0%ff%20%f1%f1%fb%eb%ea%e0

add%c0%e4ress%f0%e5%f1
add%d0%90%d0%b4ress%d1%80%d0%b5%d1%81
add%c0%e4ress%f0%e5%f1+add%d0%90%d0%b4ress%d1%80%d0%b5%d1%81
add%d0%90%d0%b4ress%d1%80%d0%b5%d1%81+add%c0%e4ress%f0%e5%f1

%5BAbCdEf%C0%E1%C2%E3%C4%E5%5D
[AbCdEf%D0%90%D0%B1%D0%92%D0%B3%D0%94%D0%B5]
%5BAbCdEf%C0%E1%C2%E3%C4%E5%5D+[AbCdEf%D0%90%D0%B1%D0%92%D0%B3%D0%94%D0%B5]
[AbCdEf%D0%90%D0%B1%D0%92%D0%B3%D0%94%D0%B5]+%5BAbCdEf%C0%E1%C2%E3%C4%E5%5D

%D0%BE%EE%D0%BF%EF%D1%86%F6%D0%B8%E8%D0%B8%E8
%EE%D0%BE%EF%D0%BF%F6%D1%86%E8%D0%B8%E8%D0%B8

= = = = = = = = = =

AbCdEfА?

опции?
опции?
опции опции?
опции опции?

Тестовая ссылка
Тестовая ссылка
Тестовая ссылка Тестовая ссылка
Тестовая ссылка Тестовая ссылка

addАдressрес
addАдressрес
addАдressрес addАдressрес
addАдressрес addАдressрес

[AbCdEfАбВгДе]
[AbCdEfАбВгДе]
[AbCdEfАбВгДе] [AbCdEfАбВгДе]
[AbCdEfАбВгДе] [AbCdEfАбВгДе]

ооппццииии
ооппццииии


 
Piter ©   (2009-08-07 21:46) [26]

TIF ©   (06.08.09 20:18) [25]
Только работает это и без вычисления вероятностей


не пиши фигни. Способ предложенный Noctis"ом лишь один из способов. Который тоже может ошибиться, особенно если его применять как универсальный для ВСЕХ языков.

TIF ©   (06.08.09 20:18) [25]
Яндекс с Google преобразуют мешашину "жёстко",


и это правильно. Строка может быть ANSI, может быть Unicode, но она никак не может быть смешанной, это против всех стандартов.


 
TIF ©   (2009-08-08 00:12) [27]

> это против всех стандартов.

В IT самое интересное - это стандарты. Как часто они появляются, так часто их и нарушают. Так что иногда приходится приспосабливаться к самому неожиданному

> Способ предложенный Noctis"ом лишь один из способов

А я о чём, собственно? :) О своём способе. Об одном из множества (хотя все способы будут во многом похожими). Я в нём обошёлся без вероятностей.
Но! В рамках поставленной передо мной задачи созданный алгоритм работает: поедает закодированную %-ами ссылку (хоть ANSI, хоть Unicode), а выдаёт правильный результат.

Да. Браузеры не будут смешивать ANSI и Unicode, но "мешанина" - это всего лишь интересная особенность алгоритма и она позволит уменьшить размер закодированной строки если заранее известно, с какой кодовой страницей будем работать.

PS: чуть не забыл. Оформлю функцию, чтобы выглядела более-менее прилично, и выложу сюда


 
Piter ©   (2009-08-08 11:20) [28]

TIF ©   (08.08.09 0:12) [27]
Так что иногда приходится приспосабливаться к самому неожиданному


ну так приспособь еще к тому, что вдруг данные в URL закодированы XOR"ом по паролю, брутфорс хотя бы встрой... Остальое комментировать просто лень, ходьба по кругу.


 
TIF ©   (2009-08-10 07:09) [29]

> Оформлю функцию, чтобы выглядела более-менее прилично, и
> выложу сюда

И выложу сюда ссылку :)

http://InfoDelphi.ru/IDLib/URLDecode



Страницы: 1 вся ветка

Форум: "Прочее";
Текущий архив: 2009.10.11;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.55 MB
Время: 0.006 c
2-1249889488
ЛД
2009-08-10 11:31
2009.10.11
DLL


2-1249914741
Putnik
2009-08-10 18:32
2009.10.11
Название элемента интерфейса


15-1248781875
TIF
2009-07-28 15:51
2009.10.11
URL-кодировка (URL encoding, Percent-encoding)


11-1206025013
andreil
2008-03-20 17:56
2009.10.11
Stream2Stream на АСМе?


2-1249655586
andi
2009-08-07 18:33
2009.10.11
сортировка





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский