62

如何检查字符串是否已经编码?

例如,如果我编码TEST==,我得到TEST%3D%3D. 如果我再次编码最后一个字符串,我会得到TEST%253D%253D,如果它已经被编码,我必须在这样做之前知道......

我已经保存了编码参数,我需要搜索它们。我不知道输入参数,它们将被编码或不编码,所以我必须知道在搜索之前是否必须对它们进行编码或解码。

4

11 回答 11

52

解码,对比原版。如果确实不同,则对原始内容进行编码。如果没有差异,则原始文件未编码。但它仍然没有说明新解码的版本是否仍未编码。递归的好任务。

我希望不能用 urlencode 编写 quine,否则这个算法会卡住。

例外:当字符串包含“+”字符时,即使字符串未经过 url 编码,url 解码器也会将其替换为空格

于 2010-02-19T09:45:58.753 回答
18

使用正则表达式检查您的字符串是否包含非法字符(即在 URL 编码字符串中找不到的字符,如空格)。

于 2010-02-19T09:50:35.893 回答
6

尝试解码网址。如果生成的字符串比原始字符串短,则原始 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
于 2016-01-07T14:22:58.203 回答
3

你不能确定,除非你的字符串符合某种模式,或者你跟踪你的字符串。正如您自己指出的那样,编码的字符串也可以编码,因此您不能通过查看字符串本身来 100% 确定。

于 2010-02-19T09:39:25.120 回答
3

软件方面的乔尔在某个时候有一个解决方案 - http://www.joelonsoftware.com/articles/Wrong.html
或者您可以在字符串中添加一些前缀。

于 2010-02-19T09:55:27.707 回答
2

检查您的 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] 可以在第 2 页的URL 规范的“不安全”部分中找到候选列表。在我的理解中,编码检查中应该省略“%”或“#”,因为这些字符可以在编码中出现网址也是如此。

于 2018-12-14T08:53:17.350 回答
2

使用 Spring UriComponentsBuilder:

import java.net.URI;
import org.springframework.web.util.UriComponentsBuilder;

private URI getProperlyEncodedUri(String uriString) {
    try {
        return URI.create(uriString);
    } catch (IllegalArgumentException e) {
        return UriComponentsBuilder.fromUriString(uriString).build().toUri();
    }
}
于 2020-02-28T11:47:03.017 回答
1

为了避免编码两次并产生错误(正如 OP 所说),我们取消引用而不是再次引用,在 Python 中这将是:

import urllib.parse
urllib.parse.unquote(str)
urllib.parse.quote(str)
于 2020-04-15T15:09:51.940 回答
0

如果您想确保字符串编码正确(如果需要编码) - 只需再次对其进行解码和编码。

元代码:

100%_correctly_encoded_string = encode(decode(input_string))

已经编码的字符串将保持不变。未编码的字符串将被编码。仅包含 url 允许字符的字符串也将保持不变。

于 2019-01-16T12:16:09.353 回答
0

根据规范(https://www.rfc-editor.org/rfc/rfc3986),所有 URL必须以一个方案开头,后跟一个:

由于需要冒号作为方案和 URI 其余部分之间的分隔符,因此任何包含冒号的字符串都不会被编码。

(这假设您不会得到一个没有方案的不完整 URI。)

所以你可以测试字符串是否包含冒号,如果没有,则对其进行urldecode,如果该字符串包含冒号,则原始字符串是url编码的,如果没有,检查字符串是否不同,如果是,则再次urldecode,如果不是,它不是有效的 URI。

如果你知道你可以期待什么样的方案,你可以使这个循环更简单。

于 2019-05-06T15:37:01.360 回答
0

感谢这个答案,我编写了一个函数(JS 语言),它只对 URL 进行一次编码,encodeURI因此您可以调用它以确保只编码一次,并且您不需要知道 URL 是否已经编码。

ES6:

var getUrlEncoded = sURL => {
    if (decodeURI(sURL) === sURL) return encodeURI(sURL)
    return getUrlEncoded(decodeURI(sURL))
}

ES6 之前:

var getUrlEncoded = function(sURL) {
    if (decodeURI(sURL) === sURL) return encodeURI(sURL)
    return getUrlEncoded(decodeURI(sURL))
}

以下是一些测试,因此您可以看到 URL 仅编码一次

getUrlEncoded("https://example.com/media/Screenshot27 UI Home.jpg")
//"https://example.com/media/Screenshot27%20UI%20Home.jpg"
getUrlEncoded(encodeURI("https://example.com/media/Screenshot27 UI Home.jpg"))
//"https://example.com/media/Screenshot27%20UI%20Home.jpg"
getUrlEncoded(encodeURI(encodeURI("https://example.com/media/Screenshot27 UI Home.jpg")))
//"https://example.com/media/Screenshot27%20UI%20Home.jpg"
getUrlEncoded(decodeURI("https://example.com/media/Screenshot27 UI Home.jpg"))
//"https://example.com/media/Screenshot27%20UI%20Home.jpg"
getUrlEncoded(decodeURI(decodeURI("https://example.com/media/Screenshot27 UI Home.jpg")))
//"https://example.com/media/Screenshot27%20UI%20Home.jpg"
于 2019-10-07T11:20:45.833 回答