Как узнать, была ли строка уже закодирована в URL? - PullRequest
46 голосов
/ 19 февраля 2010

Как я могу проверить, была ли строка уже закодирована?

Например, если я закодирую TEST==, я получу TEST%3D%3D. Если я снова закодирую последнюю строку, я получу TEST%253D%253D, я должен был бы знать перед этим, если она уже закодирована ...

Я сохранил закодированные параметры, и мне нужно их найти. Я не знаю для входных параметров, что они будут - кодированы или нет, поэтому я должен знать, должен ли я кодировать или декодировать их перед поиском.

Ответы [ 8 ]

36 голосов
/ 19 февраля 2010

Расшифруйте, сравните с оригиналом. Если он отличается, оригинал кодируется. Если это не отличается, оригинал не закодирован. Но все же это ничего не говорит о том, не была ли недавно декодированная версия еще не закодирована. Хорошее задание для рекурсии.

Я надеюсь, что никто не может написать quine в urlencode, иначе этот алгоритм застрянет.

15 голосов
/ 19 февраля 2010

Используйте regexp, чтобы проверить, содержит ли ваша строка недопустимые символы (т. Е. Символы, которые невозможно найти в строке в кодировке URL, например, пробел).

4 голосов
/ 19 февраля 2010

У Джоэла в программном обеспечении было решение для этого некоторое время назад - http://www.joelonsoftware.com/articles/Wrong.html
Или Вы можете добавить какой-то префикс в строки.

3 голосов
/ 07 января 2016

Попробуйте расшифровать URL.Если результирующая строка короче оригинала, то исходный URL уже был закодирован, иначе вы можете безопасно его кодировать (либо он не закодирован, либо даже пост-кодирование URL остается неизменным, поэтому повторное кодирование не приведет к неправильному URL).Ниже приведен пример псевдо (на основе ruby) кода:

# Returns encoded URL for any given URL after determining whether it is already encoded or not
    def escape(url)
      unescaped_url = URI.unescape(url)
      if (unescaped_url.length < url.length)
        return url
      else
        return URI.escape(url)
      end
    end
2 голосов
/ 19 февраля 2010

Вы не можете знать наверняка, если ваши строки не соответствуют определенному шаблону или вы не отслеживаете свои строки. Как вы сами отметили, закодированная строка также может быть закодирована, поэтому вы не можете быть на 100% уверены, глядя на саму строку.

0 голосов
/ 06 мая 2019

Согласно спецификации (https://tools.ietf.org/html/rfc3986) все URL-адреса ДОЛЖНЫ начинаться со схемы, за которой следует:

Поскольку в качестве разделителя между схемой и остальной частью URI требуется двоеточие, любая строка, содержащая двоеточие, не кодируется.

(Предполагается, что вам не будет предоставлен неполный URI без схемы.)

Таким образом, вы можете проверить, содержит ли строка двоеточие, если нет, url-кодировать ее, и если эта строка содержит двоеточие, исходная строка была закодирована URL-адресом, если нет, проверить, отличаются ли строки, и если да, еще раз urldecode а если нет, то это недопустимый URI.

Вы можете упростить этот цикл, если знаете, какие схемы вы можете ожидать.

0 голосов
/ 16 января 2019

Если вы хотите быть уверены, что строка закодирована правильно (если она должна быть закодирована) - просто декодируйте и кодируйте ее еще раз.

Metacode:

100%_correctly_encoded_string = encode(decode(input_string))

уже закодированная строка останется нетронутой. Некодированная строка будет закодирована. Строка, содержащая только символы, разрешенные в URL, также останется нетронутой.

0 голосов
/ 14 декабря 2018

Проверьте ваш URL на наличие подозрительных символов [1]. Список кандидатов:

WHITE_SPACE ,", < , > , { , } , | , \ , ^ , ~ , [ , ] , . и `

Я использую:

private static boolean isAlreadyEncoded(String passedUrl) {
        boolean isEncoded = true;
        if (passedUrl.matches(".*[\\ \"\\<\\>\\{\\}|\\\\^~\\[\\]].*")) {
                isEncoded = false;
        }
        return isEncoded;
}

Для фактического кодирования я продолжаю:

https://stackoverflow.com/a/49796882/1485527

Примечание : даже если ваш URL-адрес не содержит небезопасных символов, которые вы, возможно, захотите применить, например, Кодировка Punnycode для имени хоста. Таким образом, еще есть много места для дополнительных проверок.


[1] Список кандидатов можно найти в разделе «Небезопасные» спецификации URL на странице 2. В моем понимании '%' или '#' должны быть пропущены при проверке кодировки, так как эти символы могут встречаться и в закодированных URL.

...