2012-11-14 117 views
0

我目前正在努力处理iOS上转义特殊字符的百分比,例如包含在查询参数值中时的“é”。在iOS上转义特殊字符(如é)的百分比

我正在使用AFNetworking,但问题不是特定于它。

“é”字符应该百分比转义为“%E9”,但结果为“%C3%A9”。原因是因为“é”在UTF8中表示为2个字节。

实际百分比转义方法是众所周知的方法,我传递UTF8作为字符串编码。字符串本身是@“é”。

static NSString * AFPercentEscapedQueryStringPairMemberFromStringWithEncoding(NSString *string, NSStringEncoding encoding) 
{ 
    static NSString * const kAFCharactersToBeEscaped = @":/?&=;[email protected]#$()~"; 
    static NSString * const kAFCharactersToLeaveUnescaped = @"[]."; 

    return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)string, (__bridge CFStringRef)kAFCharactersToLeaveUnescaped, (__bridge CFStringRef)kAFCharactersToBeEscaped, CFStringConvertNSStringEncodingToEncoding(encoding)); 
} 

我希望通过UTF16字符串编码将解决它,但它不。结果是“%FF%FE%E9%00”,在这种情况下,它包含“%E9”,但我必须缺少一些明显的东西。

不知怎的,我无法绕过它。 任何指针都会很棒。

回答

1

RFC 3986解释说,除非您正在编码的字符属于未保留的US-​​ASCII范围,否则惯例是将字符转换为(在本例中为UTF8编码的)字节值,并使用该值作为编码百分比的基数。

你看到的行为是正确的。

针对UTF-8与UTF-16给出的编码值之间的差异是由于一些因素造成的。

编码差异

首先,有在各自的编码实际上定义方式的区别。 UTF-16将始终使用两个字节来表示其字符,并将较高位字节与较低位字节进行基本连接以定义该代码。 (这些字节的排序取决于代码是否编码为Little Endian或Big Endian。)另一方面,UTF-8使用动态数量的字节,具体取决于字符存在于Unicode代码页中的哪个位置。 UTF-8的方式涉及要使用的字节数是由第一个字节本身设置的位数。

因此,如果我们看一下C3 A9,即转化为以下位:

1100 0011 1010 1001 

看着RFC 2279,我们看到设置的“1'与终止‘开始0’表示多少字节将在这种情况下,2.删除最初的110元数据,我们从00011开始留下第一个字节:它表示实际值的最左边的位。

对于下一个字节(1010 1001),再次从RFC中我们看到,对于每个后续字节,10将作为实际值的“前缀”元数据。剥离,我们留下101001

连接实际值位,我们以00011 101001,233(以10为底)或E9(以16为底)结束。

编码识别

的另一件事从UTF-16值(%FF%FE%E9%00)具体考虑的是从原来的RFC,其中提到的是有用的编码的没有明确的定义,在编码的值本身。所以在这种情况下,iOS是“作弊”,给你一个使用什么编码的指示。 FF FE是在UTF-16编码文件中使用的众所周知的字节顺序标记,表示UTF-16是使用的编码。至于E9 00,如前所述,UTF-16总是使用两个字节。在这种情况下,由于它的所有数据都可以用1个字节表示,所以其他数据只是空的。