Base64 Over Http Post Losing Data (Objective-C)

Base64 Over HTTP POST losing data (Objective-C)

The problem is exactly what I suggested in my first comment. That is, base64 encoded data can contain '+' characters. In x-www-form-urlencoded data the receiver knows that '+' is an encoding of a space character. Thus since you aren't URL encoding your base64 value, any instances of '+' will cause the data to be corrupted when received.

The '+' characters in your initial data are turning into ' ' when received and stored. When you then output that value, it is invalid base64 encoded data.

If you examine the source of your working vs. non-working examples you'll see that the whitespace exists EXACTLY where there is a '+' in the original Base64 encoded value. Any newlines you're seeing are because whatever you're viewing the source in is wrapping lines at a ' ' character.

In your iOS code you need to properly encode the base64 encoded value, in your case all you really need to do is percent encode the '+' characters.

EDIT to add, in response to comment:

post = [post stringByReplacingOccurrencesOfString:@"+" withString:@"%2B"];

Base64 issue in NSMutableURLRequest POST message?

I know this is a old question, but for a long time I used the same solution and the problem was that we are not encoding properly the url before making the request to the server. The documentation says:

  According to RFC 3986, the reserved characters in a URL are:
reserved = gen-delims / sub-delims
gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
/ "*" / "+" / "," / ";" / "="

And here is how to encode the string:/

CFStringRef encodedString =
CFURLCreateStringByAddingPercentEscapes(
kCFAllocatorDefault,
(__bridge CFStringRef)(originalString),
NULL,
CFSTR(":/?#[]@!$&'()*+,;="),kCFStringEncodingUTF8);

And to get the string again:

    NSString* stringEncoded = CFBridgingRelease
(CFURLCreateWithString(kCFAllocatorDefault, encodedString, NULL));

I think this is the best we can do, because we make sure that string will be properly encoded and during the request the symbols will not be replaced for other thing.
here is the references:

http://developer.apple.com/library/ios/#documentation/CoreFoundation/Reference/CFURLRef/Reference/reference.html#//apple_ref/c/func/CFURLCreateStringByAddingPercentEscapes

http://developer.apple.com/library/ios/#documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/WorkingWithHTTPAndHTTPSRequests/WorkingWithHTTPAndHTTPSRequests.html

Base64 String when decoded to png is cut off with Objective-C

In terms of why it's getting cut off, I suspect you're looking at the base64 string in the debugger, which will truncate it. Actually NSLog the string and you'll see it's longer than what you're seeing in the debugger.

A couple of other unrelated observations:

  1. You should not use stringWithUTF8String with [base64 bytes] because the NSData will not be null terminated. If you really needed to convert it to a string, you'd use initWithData rather than stringWithUTF8String:

    return [[NSString alloc] initWithData:base64 encoding:NSUTF8StringEncoding];
  2. As others have pointed out, you can bypass the creation of the NSData of the base64 altogether, and create the string directly:

    return [imageData base64EncodedStringWithOptions:0];
  3. I'm not sure why you're taking the NSData from the server and round tripping it through a UIImage at all. You can theoretically just encode the data from the server directly:

    NSURL* imageUrl = [NSURL URLWithString:url];
    NSData* urlData = [NSData dataWithContentsOfURL:imageUrl];
    return [urlData base64EncodedStringWithOptions:0];

    The server is already returning you the NSData of a PNG representation. You don't need to do that UIImage and UIImagePNGRepresentation stuff at all. You're actually generating a PNG that is considerably larger than the one the server returned to you.

  4. I'd advise against using dataWithContentsOfURL, because that's a synchronous network call. You probably should use NSURLSession and change this to be an asynchronous method.

Base64 Decoding in iOS 7+

Swift 3+

let plainString = "foo"

Encoding

let plainData = plainString.data(using: .utf8)
let base64String = plainData?.base64EncodedString()
print(base64String!) // Zm9v

Decoding

if let decodedData = Data(base64Encoded: base64String!),
let decodedString = String(data: decodedData, encoding: .utf8) {
print(decodedString) // foo
}

Swift < 3

let plainString = "foo"

Encoding

let plainData = plainString.dataUsingEncoding(NSUTF8StringEncoding)
let base64String = plainData?.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
print(base64String!) // Zm9v

Decoding

let decodedData = NSData(base64EncodedString: base64String!, options: NSDataBase64DecodingOptions(rawValue: 0))
let decodedString = NSString(data: decodedData, encoding: NSUTF8StringEncoding)
print(decodedString) // foo

Objective-C

NSString *plainString = @"foo";

Encoding

NSData *plainData = [plainString dataUsingEncoding:NSUTF8StringEncoding];
NSString *base64String = [plainData base64EncodedStringWithOptions:0];
NSLog(@"%@", base64String); // Zm9v

Decoding

NSData *decodedData = [[NSData alloc] initWithBase64EncodedString:base64String options:0];
NSString *decodedString = [[NSString alloc] initWithData:decodedData encoding:NSUTF8StringEncoding];
NSLog(@"%@", decodedString); // foo

Converting a Base64 String into a UIImage

Answer was to use an external library, NSData+Base64. It implements method dataFromBase64String that returned imageData properly so it could be converted into an image.

https://github.com/l4u/NSData-Base64

imageData = [NSData dataFromBase64String:frontCheckBytesString];
checkImage = [UIImage imageWithData:imageData];

Objective C: make a POST request using SHA512

The API failed to mention that they want the signature to be base64 encoded. This site gives a pretty good example of how to do so http://agerson.net/base64-encode-and-decode-nsstring-cocoa.

I think you are also confusing encryption with signatures. The API does not appear to ask you to encrypt you data. It asks you to sign your data. The enryptedData variable you have is the signature and does not need to be encrypted. Just do base64 encode on it and assign it to the Sign header.

NSData won't accept valid base64 encoded string

Your Base64 string is not valid. It must be padded with = characters to have
a length that is a multiple of 4. In your case: "eyJlbWFp....MTM3fQ==".

With this padding, initWithBase64EncodedString decodes the Base64 string correctly.

i Have the local path of image in xcode and i want it to covert the image into base64 and send it to the php file

Download NSData+Base64 category, and add it to your project.

After that in your Controller for example.

#import "NSData+Base64.h"
.....
NSString *base64 = [[NSData dataWithContentsOfFile:path] base64EncodedString];
// Request and send your base64 string to server, as usual you're sending another string

Or if your deployment target is iOS7+, use this

NSString *base64 = [[NSData dataWithContentsOfFile:path] base64EncodedString];
// Request and send your base64 string to server, as usual you're sending another string


Related Topics



Leave a reply



Submit