2

I'm trying to encode url string using Objective-c

// 1. Get string
char res = ((char)(400));
NSString *unencodedString = [NSString stringWithFormat:@"%c",res];

// 2. Encode string
static NSString *escape = @":/?&=;+!@#$()',*[]";
NSString *result = (__bridge_transfer  NSString *)
CFURLCreateStringByAddingPercentEscapes(
                                        NULL,
                                        (__bridge CFStringRef)unencodedString,
                                        NULL,
                                        (__bridge CFStringRef)escape,
                                        kCFStringEncodingUTF8);
// result = %C2%90

But result is not that I expect. Because I get %C6%90 using other programming languages.

As you see Objective-C result is %C2%90, but I expect %C6%90.

Where is my error? Am I do something wrong?

Alexander
  • 1,228
  • 2
  • 15
  • 29
  • What is your input, what output do you expect? – L.B Feb 22 '14 at 18:44
  • he expects the output to match in all cases, @L.B ; also, I'm wondering why Alexander is xor-ing the starting character of "`1`" with "`417`"? – Michael Dautermann Feb 22 '14 at 18:48
  • The input is character with code 400. I expect to get url encoded string `%C6%C90`. Xor-ing removed from question. – Alexander Feb 22 '14 at 18:51
  • In which part/language you have the problem `HttpUtility.UrlEncode(((char)400).ToString())` returns what you say. – L.B Feb 22 '14 at 18:57
  • Objective-C code returns wrong value `%C2%90`. Other languages return `%C6%90`. I can't figure out why is it? – Alexander Feb 22 '14 at 19:01
  • @Alexander then focus on your `Objective-C code`. I don't know why you tagged it as c# – L.B Feb 22 '14 at 19:02
  • @AnthonyKong, No. It's turned out that problem was in getting NSString from char. – Alexander Feb 23 '14 at 06:03

1 Answers1

2

The problem is NSString *unencodedString = [NSString stringWithFormat:@"%c",res] doesn't do what you think it does. char res cannot hold a value larger than 128 (256 for unsigned char).

char res = ((char)(400));
NSString *unencodedString = [NSString stringWithFormat:@"%c",res];
XCTAssertEqualObjects(unencodedString, @"\xc2\x90", @"");

static NSString *escape = @":/?&=;+!@#$()',*[]";
NSString *result = (__bridge_transfer  NSString *)
CFURLCreateStringByAddingPercentEscapes(
                                        NULL,
                                        (__bridge CFStringRef)unencodedString,
                                        NULL,
                                        (__bridge CFStringRef)escape,
                                        kCFStringEncodingUTF8);

XCTAssertEqualObjects(result, @"%C2%90", @"");

Here is an example which works.

NSString *unencodedString = @"Ɛ";

static NSString *escape = @":/?&=;+!@#$()',*[]";
NSString *result = (__bridge_transfer  NSString *)
CFURLCreateStringByAddingPercentEscapes(
                                        NULL,
                                        (__bridge CFStringRef)unencodedString,
                                        NULL,
                                        (__bridge CFStringRef)escape,
                                        kCFStringEncodingUTF8);
XCTAssertEqualObjects(result, @"%C6%90", @"");

UPDATE

If you want a sample like this to work, use unichar and -stringWithCharacters:length:.

unichar res = ((unichar)(400));
NSString *unencodedString = [NSString stringWithCharacters:&res length:1];
XCTAssertEqualObjects(unencodedString, @"Ɛ", @"");

static NSString *escape = @":/?&=;+!@#$()',*[]";
NSString *result = (__bridge_transfer  NSString *)
CFURLCreateStringByAddingPercentEscapes(
                                        NULL,
                                        (__bridge CFStringRef)unencodedString,
                                        NULL,
                                        (__bridge CFStringRef)escape,
                                        kCFStringEncodingUTF8);
XCTAssertEqualObjects(result, @"%C6%90", @"");
Jeffery Thomas
  • 42,202
  • 8
  • 92
  • 117