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:
You should not use
stringWithUTF8String
with[base64 bytes]
because theNSData
will not be null terminated. If you really needed to convert it to a string, you'd useinitWithData
rather thanstringWithUTF8String
:return [[NSString alloc] initWithData:base64 encoding:NSUTF8StringEncoding];
As others have pointed out, you can bypass the creation of the
NSData
of thebase64
altogether, and create the string directly:return [imageData base64EncodedStringWithOptions:0];
I'm not sure why you're taking the
NSData
from the server and round tripping it through aUIImage
at all. You can theoretically just encode the data from the server directly:
The server is already returning you theNSURL* imageUrl = [NSURL URLWithString:url];
NSData* urlData = [NSData dataWithContentsOfURL:imageUrl];
return [urlData base64EncodedStringWithOptions:0];NSData
of a PNG representation. You don't need to do thatUIImage
andUIImagePNGRepresentation
stuff at all. You're actually generating aPNG
that is considerably larger than the one the server returned to you.I'd advise against using
dataWithContentsOfURL
, because that's a synchronous network call. You probably should useNSURLSession
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 thisNSString *base64 = [[NSData dataWithContentsOfFile:path] base64EncodedString];
// Request and send your base64 string to server, as usual you're sending another string
Related Topics
What Are My Options to Check for Viruses on a PHP Upload
Php-Paypal-Error: 14077410:Ssl Routines:Ssl23_Get_Server_Hello:Sslv3 Alert Handshake Failure
How to Remove Backslash on JSON_Encode() Function
Finding First Day of Week via PHP
Codeigniter 3 - Access Session from Outside Codeigniter Installation
Can a PHP File Name (Or a Dir in Its Full Path) Have Utf-8 Characters
Php/MySQL with Encoding Problems
Remove Extra Spaces But Not Space Between Two Words
Reload the Page After Ajax Success
Customizing My-Account Addresses Fields in Woocommerce 3
Laravel: How to Use Multiple Pivot Table Relationships
File_Get_Contents(): Stream Does Not Support Seeking/When Was PHP Behavior About This Changed