我如何检查字符串是否已被编码?
例如,如果我对TEST==
进行编码,则会得到TEST%3D%3D
。如果我再次对最后一个字符串进行编码,我会得到TEST%253D%253D
,如果它已经编码,我必须知道...
我已保存编码参数,我需要搜索它们。我不知道输入参数,它们是什么 - 编码与否,所以我必须知道在搜索之前是否必须对它们进行编码或解码。
答案 0 :(得分:37)
解码,与原始相比。如果它确实不同,则原始编码。如果没有差异,则不对原始编码进行编码。但它仍然没有说明新解码的版本是否仍未编码。递归的好任务。
我希望你不能在urlencode中写一个quine,否则这个算法就会卡住。
答案 1 :(得分:15)
使用正则表达式检查您的字符串是否包含非法字符(即在URL编码的字符串中找不到的字符,如空格)。
答案 2 :(得分:4)
乔尔在软件上有一个解决方案 - http://www.joelonsoftware.com/articles/Wrong.html 或者您可以在字符串中添加一些前缀。
答案 3 :(得分:3)
尝试解码网址。如果生成的字符串比原始字符串短,则原始URL已经编码,否则您可以安全地对其进行编码(或者它未编码,或者甚至编码后的url保持原样,因此再次编码不会导致错误的URL )。下面是示例伪(受红宝石启发)代码:
# 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
答案 4 :(得分:2)
除非你的琴弦符合某种模式,否则你无法确定,或者你跟踪你的琴弦。正如您自己所指出的,编码的字符串也可以编码,因此通过查看字符串本身无法100%确定。
答案 5 :(得分:1)
为了避免两次编码并生成错误(如OP所述),我们取消引用,然后再次引用,在Python中将是:
import urllib.parse
urllib.parse.unquote(str)
urllib.parse.quote(str)
答案 6 :(得分:0)
检查您的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
注意:即使您的网址不包含不安全的字符,您也可能希望应用该字符,例如Punnycode编码为主机名。因此,仍有大量空间可以进行其他检查。
[1]可在第2页的URL spec的“不安全”部分中找到候选列表。 据我了解,在编码检查中应省略'%'或'#',因为这些字符也可能出现在编码的URL中。
答案 7 :(得分:0)
如果您想确保字符串已正确编码(如果需要编码),只需再次解码并编码。
元代码:
100%_correctly_encoded_string = encode(decode(input_string))
已经编码的字符串将保持不变。未编码的字符串将被编码。仅包含允许使用网址的字符的字符串也将保持不变。
答案 8 :(得分:0)
根据规范(https://tools.ietf.org/html/rfc3986),所有URL 必须均以一个方案开头,后跟一个:
由于必须使用冒号作为方案和URI其余部分之间的分隔符,因此不会对任何包含冒号的字符串进行编码。
(这假设您将获得没有方案的不完整URI。)
因此,您可以测试字符串是否包含冒号,如果没有,则对其进行URL解码,如果该字符串包含冒号,则对原始字符串进行URL编码,如果不是,则检查字符串是否不同,如果相同,则再次进行URLdecode否则,它不是有效的URI。
如果您知道可以期望的方案,则可以使此循环更简单。
答案 9 :(得分:0)
由于this answer,我编写了一个函数(JS语言),该函数使用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"
答案 10 :(得分:0)
使用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();
}
}