0

現在、iOS で特殊文字をエスケープするパーセントに苦労しています。たとえば、クエリ パラメータ値に含まれている場合は「é」です。

AFNetworking を使用していますが、問題は AFNetworking に固有のものではありません。

「é」文字は「%E9」にパーセントエスケープする必要がありますが、結果は「%C3%A9」になります。その理由は、UTF8 では「é」がその 2 バイトで表されるためです。

実際のパーセント エスケープ方法はよく知られている方法で、文字列エンコーディングとして UTF8 を渡しています。文字列自体は @"é" です。

static NSString * AFPercentEscapedQueryStringPairMemberFromStringWithEncoding(NSString *string, NSStringEncoding encoding) 
{
    static NSString * const kAFCharactersToBeEscaped = @":/?&=;+!@#$()~";
    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" が含まれていますが、明らかな何かが欠けているに違いありません。

なんだか頭が追いつかない。どんなポインタでも素晴らしいでしょう。

4

1 に答える 1

1

RFC 3986では、エンコードしている文字が予約されていない US-ASCII の範囲に収まらない限り、文字を (この場合は UTF8 でエンコードされた) バイト値に変換し、その値をパーセントとして使用するのが規則であると説明しています。エンコーディングベース。

あなたが見ている動作は正しいです。

UTF-8 と UTF-16 で指定されたエンコードされた値の違いは、いくつかの要因によるものです。

エンコーディングの違い

まず、それぞれのエンコーディングが実際に定義される方法に違いがあります。UTF-16 は常に 2 バイトを使用してその文字を表し、基本的に上位バイトと下位バイトを連結してコードを定義します。(これらのバイトの順序は、コードがリトル エンディアンとビッグ エンディアンのどちらでエンコードされているかによって異なります。) 一方、UTF-8 では、文字が Unicode コード ページのどこに存在するかに応じて、動的なバイト数が使用されます。UTF-8 が使用するバイト数を関連付ける方法は、最初のバイト自体に設定されているビットによるものです。

したがって、C3 A9 を見ると、次のビットに変換されます。

1100 0011 1010 1001

RFC 2279を見ると、「1」の最初のセットと「0」で終わるものが、使用されるバイト数を示していることがわかります。この場合は、2 です。最初の110メタデータを取り除くと00011、最初のバイトから残ります。 : 実際の値の左端のビットを表します。

次のバイト ( 1010 1001) については、RFC から、後続のすべてのバイト10が実際の値の「プレフィックス」メタデータになることがわかります。それを取り除くと、 が残ります101001

実際の値のビットを連結すると00011 101001233base-10 またはE9base-16 の になります。

エンコーディング識別

UTF-16 値 ( %FF%FE%E9%00) から具体的に考慮すべきもう 1 つのことは、元の RFC からのもので、エンコードされた値自体には、使用されるエンコードの明示的な定義がないことが言及されています。したがって、この場合、iOS は「不正行為」を行っており、どのエンコーディングが使用されているかがわかります。 FF FEは、UTF-16 が使用されるエンコーディングであることを示すために、UTF-16 でエンコードされたファイルで使用されるよく知られたバイト順マークです。に関してはE9 00、前述のように、UTF-16 は常に 2 バイトを使用します。この場合、そのデータはすべて 1 バイトで表現できるため、もう一方は単純に null です。

于 2012-11-14T15:00:17.397 に答える