Символ ç закодирован в URL как% E7.Вот как ISO-8859-1 кодирует.Набор символов ISO-8859-1 представляет символ с одним байтом.Байт, который представляет ç, может быть выражен в шестнадцатеричном виде как E7.
В Unicode ç имеет кодовую точку U + 00E7.В отличие от ISO-8859-1, в котором кодовая точка (E7) совпадает с кодировкой (E7 в шестнадцатеричном формате), Unicode имеет несколько схем кодирования, таких как UTF-8, UTF-16 и UTF-32.UTF-8 кодирует U + 00E7 (ç) как два байта - C3 A7.
См. здесь для других способов кодирования ç.
Что касается того, почему U + 00E7 и E7 в ISO-8859-1 оба используют «E7», первые 256 кодовых точек в Unicode были сделаны идентичными ISO-8859-1 .
Если бы этот URL был UTF-8, ç был бы закодирован как% C3% A7.Мое (очень ограниченное) понимание RFC2616 заключается в том, что кодировкой по умолчанию для URL является (в настоящее время) ISO-8859-1.Следовательно, это, скорее всего, URL-код в формате ISO-8859-1.Это означает, что наилучшим подходом, вероятно, является проверка правильности кодировки, а если нет, то предположим, что это ISO-8859-1 и транскодирование в UTF-8:
unless query.valid_encoding?
query.encode!("UTF-8", "ISO-8859-1", :invalid => :replace, :undef => :replace, :replace => "")
end
Вот процесс в IRB (плюс побег в конце для развлечения)
a = CGI.unescape("%E7")
=> "\xE7"
a.encoding
=> #<Encoding:UTF-8>
a.valid_encoding?
=> false
b = a.encode("UTF-8", "ISO-8859-1") # From ISO-8859-1 -> UTF-8
=> "ç"
b.encoding
=> #<Encoding:UTF-8>
CGI.escape(b)
=> "%C3%A7"