如何正确地使用Unicode解码URL在C
问题描述:
从我的引用记录我试图解码引用,但它看起来像%81
和%8A
是无效的百分比编码,所以我得到ri�0�9o
。如何正确地使用Unicode解码URL在C
我需要通过websocket发送解码的字符串,现在我在浏览器端获得Could not decode a text frame as UTF-8.
。
这些甚至是有效的百分比编码?我怎么知道他们是否有效?
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
void urldecode2(char *dst, const char *src) {
char a, b;
while(*src) {
if((*src == '%') && ((a = src[1]) && (b = src[2])) && (isxdigit(a) && isxdigit(b))) {
if(a >= 'a')
a -= 'a'-'A';
if(a >= 'A')
a -= ('A' - 10);
else
a -= '0';
if(b >= 'a')
b -= 'a'-'A';
if(b >= 'A')
b -= ('A' - 10);
else
b -= '0';
*dst++ = 16*a+b;
src+=3;
} else if(*src == '+') {
*dst++ = ' ';
src++;
} else {
*dst++ = *src++;
}
}
*dst++ = '\0';
}
int main() {
const char *in = "http://www.google.co.in/search?q=cari%810%8A9o";
char out[100];
urldecode2(out, in);
printf("%s\n", out);
return 0;
}
答
%81
和%8A
是完全有效的%-escapes,但结果不是UTF-8字符串。 URL不需要是UTF-8字符串,但现在通常是这样。
它在我看来像一些非常奇怪的双重编码已经发生。没有我知道的约定使用三位数百分比的编码,但这就是您在该URL中看起来的样子。假设打算编码西班牙语单词“cariño”(care,affection,fondness),它应该是UTF-8中的cari%C3%B1o
,或ISO-8859-1/Windows-1252中的cari%F1o
(通常显示在URL中意外)。
有效UTF-8序列的规则非常简单,您可以使用正则表达式检查有效序列。并非所有的有效序列都映射到字符,其中66个被明确映射为“不是字符”,但是所有有效序列都应该被符合的解码器接受,即使它后来拒绝解码的字符在语义上是不正确的。
的UTF-8序列是对应于以下模式中的一个的一对四字节序列:(从Unicode标准拍摄,表3.7)
Byte 1 Byte 2 Byte 3 Byte 4
------ ------ ------ ------
00..7F -- -- --
C2..DF 80..BF -- --
E0 A0..BF 80..BF --
E1..EC 80..BF 80..BF --
ED 80..9F 80..BF --
EE..EF 80..BF 80..BF --
F0 90..BF 80..BF 80..BF
F1..F3 80..BF 80..BF 80..BF
F4 80..8F 80..BF 80..BF
别的是非法的。 (因此编码C0,C1和F5到FF根本不出现。)特别是,十六进制码81和8A永远不能启动UTF-8序列。
既然没有什么好的方法可以知道无效序列的含义,最简单的办法就是将它们去掉。
'%81'和'%8A'完全有效%-escapes,但结果不是UTF-8字符串。你认为搜索字符串是什么,用人类可读的字符? – rici
谢谢你指出。被这个推荐人打的网站是西班牙文,我认为它应该是'cariño'。虽然这个网站是来自www.google.co.in。 –
- 是%c3%b1。我不知道你引用的代码来自哪里。 – rici