如何检查字符串是否已经被编码?
例如,如果我对TEST==
进行编码,我会得到TEST%3D%3D
。 如果我再次对最后一个字符串进行编码,我会得到TEST%253D%253D
,在这之前我需要知道它是否已经被编码了...
我保存了已编码的参数,并且需要搜索它们。 我不知道输入参数是编码还是未编码的,因此在搜索之前我需要知道是否必须对它们进行编码或解码。
如何检查字符串是否已经被编码?
例如,如果我对TEST==
进行编码,我会得到TEST%3D%3D
。 如果我再次对最后一个字符串进行编码,我会得到TEST%253D%253D
,在这之前我需要知道它是否已经被编码了...
我保存了已编码的参数,并且需要搜索它们。 我不知道输入参数是编码还是未编码的,因此在搜索之前我需要知道是否必须对它们进行编码或解码。
解码并与原始内容进行比较。如果不同,则原始内容已被编码。如果没有差异,则原始内容未被编码。但仍然不能确定新解码版本是否仍然被编码。递归的好任务。
希望urlencode无法编写Quine程序,否则此算法将被卡住。
例外情况:当字符串包含“+”字符时,url解码器会将其替换为空格,即使该字符串没有进行url编码。
%DESCRIPTION%
的Windows变量名,则会失败,该名称解码为ÞSCRIPTION%
,或者像%ABOUT%
这样的变量名则变成了«OUT%
。 - benrifkah使用正则表达式检查您的字符串是否包含非法字符(即在URL编码字符串中找不到的字符,例如空格)。
hello%20world
和interest20%growth
?第一个是有效的URL编码字符串,而另一个字符串必须进行转义,并且不能产生有效的反转义。 - SF.尝试解码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
除非您的字符串符合某种模式,或者您跟踪您的字符串,否则您无法确定。正如您自己指出的那样,编码的字符串也可以被重新编码,因此仅通过查看字符串本身,您不能百分之百确定。
请检查您的URL是否存在可疑字符[1]。以下是可能存在问题的字符列表:
空格,", <,>,{,},|,\,^,~,[,],.
和`
我使用的是:
private static boolean isAlreadyEncoded(String passedUrl) {
boolean isEncoded = true;
if (passedUrl.matches(".*[\\ \"\\<\\>\\{\\}|\\\\^~\\[\\]].*")) {
isEncoded = false;
}
return isEncoded;
}
对于实际编码,我采用以下方法:
https://dev59.com/8Ggv5IYBdhLWcg3wMN0U#49796882
注意:即使您的URL不包含不安全字符,您可能仍希望对主机名应用Punnycode编码等。因此,仍有很多空间进行额外的检查。
[1] 候选列表可以在URL规范第2页的“不安全”部分中找到。在我看来,“%”或“#”应该在编码检查中留出,因为这些字符也可能出现在编码的URL中。
使用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();
}
}
根据规范(https://www.rfc-editor.org/rfc/rfc3986),所有的URL 必须 以方案后跟一个 : 开始。
由于冒号是方案和URI其余部分之间的分隔符,任何包含冒号的字符串都不会被编码。
(这假设您不会收到没有方案的不完整URI。)
因此,您可以测试字符串是否包含冒号,如果没有,则对其进行urldecode,如果该字符串包含冒号,则原始字符串已经进行了url编码,如果没有,则检查字符串是否不同,如果是,则再次进行urldecode,如果不是,则它不是有效的URI。
如果您知道可以预期哪些方案,则可以使此循环更简单。
如果您想确保字符串已正确编码(如果需要编码),只需解码并再次进行编码即可。
元代码:
100%_correctly_encoded_string = encode(decode(input_string))
已经编码的字符串将保持不变。未编码的字符串将被编码。只包含URL允许字符的字符串也将保持不变。
encodeURI
一次对URL进行编码,因此您可以调用它以确保仅对其进行一次编码,而无需知道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"