与cflcreatestringbyaddingpercentescapes编码使用的大小写混淆



我想要URL编码完成。我的输入字符串是"ChBdgzQ3qUpNRBEHB+bOXQNjRTQ="

我得到一个输出为"ChBdgzQ3qUpNRBEHB%2BbOXQNjRTQ%3D",这是完全正确的,除了被编码的情况。

理想情况下,它应该是"ChBdgzQ3qUpNRBEHB%2bbOXQNjRTQ%3d"而不是我得到的输出。也就是说我应该得到%2b和%3d而不是%2b和%3d

这能做到吗?

我使用的代码如下:
NSString* inputStr = @"ChBdgzQ3qUpNRBEHB+bOXQNjRTQ=";
NSString* outputStr = (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
                                                                          (CFStringRef)inputStr,
                                                                          NULL,
                                                                          (CFStringRef)@"!*'"();:@&=+$,/?%#[]% ",
                                                                          CFStringConvertNSStringEncodingToEncoding(encoding));

另一种可能更优雅但更慢的方法是循环遍历字符串,逐个转换字符串中的每个字符(这样您将获得字符串的长度,然后从中获得从位置0到长度-1的子字符串,每次使用一个字符,然后只翻译该子字符串。如果返回的字符串长度> 1,则CFURLCreateStringByAddingPercentEscapes对该字符进行了编码,并且可以安全地将其转换为小写。

在所有情况下,您都将返回的(可能修改的)字符串附加到可变字符串上,完成后,您就得到了您想要的任何可能的字符串。尽管这看起来是一个真正的处理器独占,但实际上您可能永远不会注意到额外消耗的周期。

同样,第二种方法是首先转换整个字符串,然后逐个字节地将其复制到可变字符串,如果找到"%",则将接下来的两个字符转换为小写。只是用一种稍微不同的方式来划分问题。

您可以使用正则表达式来执行post操作:

NSMutableString *finalStr = outputStr.mutableCopy;
NSRegularExpression *re = [[NSRegularExpression alloc] initWithPattern:@"(?<=%)[0-9A-F]{2}" options:0 error:nil];
for (NSTextCheckingResult *match in [re matchesInString:escaped options:0 range:NSMakeRange(0, escaped.length)]) {
    [finalStr replaceCharactersInRange:match.range withString:[[escaped substringWithRange:match.range] lowercaseString]];
}

代码使用正则表达式:

(<?=%)[0-9A-F]{2}

匹配两个十六进制字符,只有在前面有百分号时才匹配。然后在可变字符串中迭代并替换每个匹配项。我们不必担心偏移量的变化,因为替换字符串总是相同的长度。

最新更新