在我的推荐人日志中,我正在尝试解码引荐来源,但看起来%81
和%8A
的编码百分比无效,因此我得到了ri�0�9o
。
我需要通过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;
}
答案 0 :(得分:2)
%81
和%8A
完全有效%-escapes,但结果不是UTF-8字符串。 URL不需要是UTF-8字符串,但现在它们通常都是。
在我看来,发生了一些非常奇怪的双重编码。我不知道哪个使用三位数的%-encodings,但这就是你在该URL中的样子。假设意图是对西班牙语单词“cariño”(照顾,感情,喜爱)进行编码,它应该是cari%C3%B1o
的UTF-8,或cari%F1o
的ISO-8859-1 / Windows-1252(通常意外地显示在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序列。
由于没有好的方法可以知道无效序列的含义,最简单的方法就是将它们剥离出去。