如何正确地使用Unicode解码URL在C

如何正确地使用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; 
} 
+0

'%81'和'%8A'完全有效%-escapes,但结果不是UTF-8字符串。你认为搜索字符串是什么,用人类可读的字符? – rici

+0

谢谢你指出。被这个推荐人打的网站是西班牙文,我认为它应该是'cariño'。虽然这个网站是来自www.google.co.in。 –

+0

- 是%c3%b1。我不知道你引用的代码来自哪里。 – rici

%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序列。

既然没有什么好的方法可以知道无效序列的含义,最简单的办法就是将它们去掉。