Текущий архив: 2009.10.11;
Скачать: CL | DM;
Вниз
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;
Скачать: CL | DM;
Память: 0.55 MB
Время: 0.005 c