Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/390.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何确定字符串是否已被URL编码?_Java_Utf 8_Url Encoding - Fatal编程技术网

Java 如何确定字符串是否已被URL编码?

Java 如何确定字符串是否已被URL编码?,java,utf-8,url-encoding,Java,Utf 8,Url Encoding,如何检查字符串是否已编码 例如,如果我编码TEST==,我会得到TEST%3D%3D。如果我再次对最后一个字符串进行编码,我会得到TEST%253D%253D,在这样做之前,我必须知道它是否已经编码 我已经保存了编码参数,我需要搜索它们。我不知道输入参数是什么-编码还是不编码,所以我必须知道在搜索之前是否必须对它们进行编码或解码。除非字符串符合特定模式,或者您跟踪字符串,否则您无法确定。正如您自己所指出的,编码的字符串也可以被编码,因此您无法通过查看字符串本身来100%确定。解码,与原始字符串进

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

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


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

除非字符串符合特定模式,或者您跟踪字符串,否则您无法确定。正如您自己所指出的,编码的字符串也可以被编码,因此您无法通过查看字符串本身来100%确定。

解码,与原始字符串进行比较。如果它确实不同,则对原始文件进行编码。如果不存在差异,则不会对原始文件进行编码。但它仍然没有说明新解码的版本是否仍然编码。递归的一个好任务

我希望人们不能用urlencode编写quine,否则这个算法会陷入困境


例外情况:当字符串包含“+”字符时,即使该字符串不是url编码的,url解码器也会将其替换为空格。

使用regexp检查您的字符串是否包含非法字符(即,在url编码的字符串中找不到的字符,如空格)。

Joel on软件有一个解决方案
或者您可以在字符串中添加一些前缀。

尝试解码url。如果生成的字符串比原始字符串短,则原始URL已经编码,否则您可以安全地对其进行编码(要么它未编码,要么甚至后编码URL保持原样,因此再次编码不会导致错误的URL)。下面是示例伪代码(受ruby启发):

#确定任何给定URL是否已编码后,返回该URL的编码URL
def转义(url)
unescaped_url=URI.unescape(url)
if(未缩放的url.length
检查您的URL是否有可疑字符[1]。 候选人名单:

WHITE\u SPACE,,,,<,>,{,},|,\,^,~,[,],.
和`

我使用:

private static boolean isAlreadyEncoded(String passedUrl) {
        boolean isEncoded = true;
        if (passedUrl.matches(".*[\\ \"\\<\\>\\{\\}|\\\\^~\\[\\]].*")) {
                isEncoded = false;
        }
        return isEncoded;
}
私有静态布尔值isAlreadyEncoded(字符串passedUrl){
布尔isEncoded=true;
if(passedUrl.matches(“.[\\\\”\\\\\{\\\\\\\\\\\\\\\\\\^~\[\\\].])){
isEncoded=假;
}
返回已编码;
}
对于实际编码,我将继续:

注意:即使您的URL不包含不安全的字符,您也可能希望对主机名应用Punnycode编码。因此,仍有很大的空间进行额外检查


[1] 候选人名单可在第2页的“不安全”部分找到。
据我所知,编码检查中应省略“%”或“#”,因为这些字符也可以出现在编码的URL中。

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

元代码:

100%_correctly_encoded_string = encode(decode(input_string))
已编码的字符串将保持不变。未编码的字符串将被编码。只有url允许字符的字符串也将保持不变。

根据规范()所有url必须以方案开头,后跟:

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

(这假设不会为您提供没有方案的不完整URI。)

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

如果您知道可以使用什么方案,则可以简化此循环。

多亏了我编写了一个函数(JS语言),该函数使用
encodeURI对URL进行了一次编码,因此您可以调用它以确保只对URL进行了一次编码,而不需要知道URL是否已经编码

ES6:

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"

使用Spring组件Builder:

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();
    }
}

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

import urllib.parse
urllib.parse.unquote(str)
urllib.parse.quote(str)

我没有这样做,但这是解决方案。那么,您如何区分
hello%20world
interest20%增长
?第一个是有效的urlencoded字符串,另一个是必须转义的字符串,并且不会生成有效的unescape。检查非法字符不包括百分比符号,因为它不是非法的,只是转义而已。检查百分比符号时,如果后跟“25”,则可能有一个URI编码的字符串。只有当您知道您的输入不是编码的,就是只编码了1次,并且输入自然不包含URI编码生成的序列时,这才有效。不幸的是,这不是解决方案。我将URL作为URL加密字符串传递,因此我进行了重新查找(“:”,str),无论字符串是否加密,它都返回6(https:)。如果字符串包含无效字符,您可以证明它未编码,但如果它只包含有效字符和百分号,则不能证明它已编码。这是不可知的。因此,这可能是一个很好的检查,就像一个现实的检查一样。也许更好:一个包装器类型
struct QuotedString{char*str;}
来传递,然后你可以显式地(并且可以找到)弄乱它的内部;如果0.01%的用户真的希望程序不起作用,那么它对他们就不起作用。有时,额外的extreme子句不值得付出努力和开销。如果字符串包含windows var,则此操作将失败
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();
    }
}
import urllib.parse
urllib.parse.unquote(str)
urllib.parse.quote(str)