How to decode an encoded string? - objective-c

While decoding,I am getting NSData bytes by decoding a string.I am converting NSData bytes as string:
-(void)decodeAction:(NSString*)str
{
NSData *data=[NSData base64DataFromString:str];
NSString *stt=[NSString stringWithFormat:#"%#",data];
printf("\n stt %s",[stt UTF8String]);
}
Then I am getting the following output:
<4f7c204d 6c204d61 604d6164 61616461
6164616e 24616e20 4d6e204d 6e204d6f
604d6f68 616f6861 6f68616e 28616e>

You probably want:
NSString *stt = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
or something along those lines.

Related

Unable to decode gzipped Base64 NSString

So I'm trying to decode a base64 encoded string but I'm not having any luck.. decodedString is always null! I've tried for hours and totally out of ideas. Even tried third party libraries.
Code:
NSString *input = #"H4sIAAAAAAAEALWSTW/TQBCG/0q15wTN7Je9voU2RFFUFCnuASGE9mMcTB0n9QcSQvx3xm6QWsSFAzev53l3Zp9dcb8+HFab9fZOFGJ/3Ny+bbvdrt+MX56ePp9OeDyKhSi3TJWr+z0zEtAtQS1RligLowowbxSAzqWdyA/7NUMP+7tVueb12FPXi5vi5uOP+XubuJoHkpjQOghBW5c5Dzpo0sZj8FYaztVtP6MSeHG+XIMKpJQEQQcgnSobrHVRxco6qY2WcgoOdHq4NkKzENV7fyKOrnx3brneXNeHoavjY+PbxD+jb6hNfg7BQlCqh7Kesb+eNkfjZM65R/o+zxUpwxAzTyoinyL5hLnPJBkbK6h8YPTSnb9SHGbcGcgQfJDBWY0qhop5ixoJdRYUMZ6oedf44zzO5G1ftxxEqbSx4uenufVvr/9vile3MJndPbeaxPaD715YskswS4WlxAKhgCnASv+wKPMSTYHuuf7NN3XyA92ex3bgTdU/mB8vU/Iw+GHsOfpa2MvrFEGBTSEjrPiRVImCT8T7qJSMs5VJbPMX5JgDcAQDAAA=";
NSData *decodedData = [[NSData alloc] initWithBase64EncodedString:input options:0];
NSString *decodedString = [[NSString alloc] initWithData:decodedData encoding:NSUTF8StringEncoding];
NSLog(#"Decode String Value: %#", decodedString);
The Base64 decoded output is not a string, it is binary data.
You are getting nil returned because it is not a UTF-8 string and arbitrary data is generally not valid UTF-8.
Decode using NSDataBase64DecodingIgnoreUnknownCharacters to avoid the decoder discarding non-Base-64 bytes.
NSData *decodedData = [[NSData alloc]initWithBase64EncodedString:input
options:NSDataBase64DecodingIgnoreUnknownCharacters];
Once you have decodedData, you can decompress the buffer with whatever function or library you decide on, then you can read the string. You may want to look at the answer here for an idea of how to decompress your data.
decodedData is not nil.
It's value is: <1f8b0800 ...
1f8b let me think it's a GZip.
Any hex data is not convertible as such into a String using UTF8 Encoding. UTF8 doesn't have value for each possible hex. There are non-valid combination, and so your final string is nil.
For instance, transform an UIImage into PNG HexData (using UIImagePNGRepresentation()) and try it to convert it into a NSString using NSUTF8StringEncoding. You'll see.
Using the code of https://github.com/nicklockwood/GZIP/ (first one I found):
NSData *unzippedData = [decodedData gunzippedData];
NSString *decodedString = [[NSString alloc] initWithData:unzippedData encoding:NSUTF8StringEncoding];
Output:
"MESSAGEID":"PgGCBnrKKsGuhqq_mm1gg","TIMESTAMP":"2019-03-12T12:53:05.3004826","TYPE":"UPDATE","users" : [{"userId":"8be21d1690bb46979a04b4e45a1ba625","insId":"20","operId":"30222e0b4b0e4df6b669c3cf69245422","itemUserId":15,"fName":"Aaron","lName":"Strickland","calendarId":0,"editTime":"2019-03-12T12:53:05.3815928","keyId":"ce71bc7ae3c145adad18a72e56cf0fab","projectId":"950710ab2b96413cbfd186141e147b3e","delFlag":0,"userPin":"123456"}],"keys" : [{"keyId":"ce71bc7ae3c145adad18a72e56cf0fab","projectId":"950710ab2b96413cbfd186141e147b3e","insId":"20","itemKeyId":15,"startTime":"2016-05-31T21:10:00","endTime":"2019-03-28T15:19:00","validateCount":13,"editTime":"2019-03-12T12:53:05.3815928","updateStatus":1,"delFlag":0,"calendarId":"b306db7e1f924fdebade3813dd596f5d"}]
Seems almost like JSON. I would have add "{" and "}" around it.
With a little of workaround:
NSMutableData *finalData = [[NSMutableData alloc] initWithData:[#"{" dataUsingEncoding:NSUTF8StringEncoding]];
[finalData appendData:unzippedData];
[finalData appendData:[#"}" dataUsingEncoding:NSUTF8StringEncoding]];
NSData *dictionary = [NSJSONSerialization JSONObjectWithData:finalData options:0 error:nil];
NSLog(#"dictionary: %#", dictionary);
It's up to you to know why the syntax is strange, but with that you a "usable" NSDictionary.

Encode and Decode a string on Objective C

I use below code to encode and decode a string on objective C. The encoding is good, I debug and see that it throw a hash string when input is #"1". But when I try to decode this hash string, it return nil.
Please help me.
+(NSString *)encrypt: (NSString*) input
{
//Base64 Encoding
char base64Result[32];
size_t theResultLength = 32;
Base64EncodeData(input, 20, base64Result, &theResultLength);
NSData *theData = [NSData dataWithBytes:base64Result length:theResultLength];
NSString *base64EncodedResult = [[NSString alloc] initWithData:theData encoding:NSUTF8StringEncoding];
NSString* decryptedString = [self decrypt:base64EncodedResult];
return [base64EncodedResult autorelease];
}
+ (NSString *) decrypt:(NSString*) input{
Byte inputData[[input lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];//prepare a Byte[]
[[input dataUsingEncoding:NSUTF8StringEncoding] getBytes:inputData];//get the pointer of the data
size_t inputDataSize = (size_t)[input length];
size_t outputDataSize = EstimateBas64DecodedDataSize(inputDataSize);//calculate the decoded data size
Byte outputData[outputDataSize];//prepare a Byte[] for the decoded data
Base64DecodeData(inputData, inputDataSize, outputData, &outputDataSize);//decode the data
NSData *theData = [[NSData alloc] initWithBytes:outputData length:outputDataSize];//create a NSData object from the decoded data
NSString *result = [[NSString alloc] initWithData:theData encoding:NSUTF8StringEncoding];
return [result autorelease];
}
In you encoding method, you have to convert the input string to a byte buffer and feed that to Base64EncodeData:
NSData *inputData = [input dataUsingEncoding:NSUTF8StringEncoding];
Base64EncodeData([inputData bytes], [inputData length], base64Result, &theResultLength, NO);
(The NSString *input argument in the encoding method points to an Objective-C structure, not to a C string. So your encoding method seems to work. It encodes something, but not the input string. The decoding method then fails at
NSString *result = [[NSString alloc] initWithData:theData encoding:NSUTF8StringEncoding];
because the decoded data does not contain valid UTF-8.)

How to encode NSData raw bytes directly to UTF-16 (Unicode)?

Environment: iOS Xcode Objective-C Garbled Unicode UTF-16
My Question:
I got the file content from a remote file and then stored it into NSData object, then I want to convert the NSData to Unicode encoding (note: not UTF-8,UTF-16 will okay), the problem is that I do not know the original file content encoding, what can I do to convert the unknown raw bytes into Unicode (UTF-16)?
I have tried so many method, but no one successfully touch my target, the code:
NSData *chunk = [NSData dataWithContentsOfURL:url];
NSString* newStr = [[[NSString alloc] initWithData:chunk encoding:NSUTF16LittleEndianStringEncoding] autorelease];
NSData* d = [newStr dataUsingEncoding:NSUnicodeStringEncoding];
[d writeToFile:newFilePath atomically:YES];
got the file into NSData, encode it into Unicode and write to file.
NSString* converted_str = [[NSString alloc] initWithData:chunk encoding:NSUTF8StringEncoding];
NSData * d = [(id)CFStringCreateExternalRepresentation(NULL, (CFStringRef)converted_str, kCFStringEncodingUnicode, 0) autorelease];
[d writeToFile:newFilePath atomically:YES];
convert the NSData to NSString, then restore it into NSData for write to file, not work.
[converted_str writeToFile:newFilePath atomically:YES encoding:NSUnicodeStringEncoding error:&error];
write to file directly using NSString object, garbled.
CFStringRef converted_str = CFStringCreateWithBytes(NULL, [chunk bytes],[chunk length], kCFStringEncodingUTF8,false);
CFStringRef newStr = [chunk dataUsingEncoding:NSUTF8StringEncoding];
NSData * d = [(id)CFStringCreateExternalRepresentation(NULL, (CFStringRef)big5Str, NSUnicodeStringEncoding, 0) autorelease];
[d writeToFile:newFilePath atomically:YES];
Using cString to do the encoding work, but also failure.
char converted[([chunk length] + 1)];
[chunk getCString:converted maxLength:([chunk length] + 1) encoding: NSWindowsCP1251StringEncoding];
NSLog(#"converted:%s", converted);
NSString *converted_str = [NSString stringWithCString:converted encoding:NSUnicodeStringEncoding];
NSLog(#"converted_str:%#", converted_str);
I also using usedEncoding:&xxx to get the original file encoding, then try to decode it into string object using the returned encoding, ..., failure again.
NSStringEncoding encoding;
NSString *chunk = [[NSString alloc] initWithContentsOfURL:[rb fileURL] usedEncoding:&encoding error:&error];
...
I then try to using kCFStringEncodingUTF16 to get the Unicode encoded buffer, but failure.
NSStringEncoding encode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingUTF16);
NSString *chunk = [NSString stringWithContentsOfURL:url encoding:encode error:&error];
In the end, I want to try libiconv for iOS( iPhone,iPad), but the trouble is the encoding of source content is unknown, the usedEncoding:&xxx function can not always work.
I have no idea of this trouble ... :(
Is there someone meet the similar question, please give me some direction, any answer will be most appreciated , thank you.
Sincerely wishing you and your family happiness and health.

convert base64 decoded NSData to NSString

I'm trying to encode and decode base64 data. but while decoding the base64 data, it returns bunch of hex values, but i couldn't display or printout using NSlog to the original readable strings. The below code couldn't print anything, just empty.
Can anyone help ? thanks
>
>
NSString* msgEncoded = [[NSString alloc] initWithFormat:#"Q1NNKE1DTC9TTUEgUkNWL2FkbWluQHNldGVjcy5jb20gT1JHLyBUVkIvNDNkYzNlMzQwYWQ3Yzkp:"];
NSData* decoded = [[NSData alloc] initWithData:[self decodeBase64WithString:msgEncoded]];
NSString* plainString = [[NSString alloc]initWithData:decoded encoding:NSUTF8StringEncoding];
NSLog(#"\n Decoded string: %# \n", plainString );
There is a built in function in NSData
[data base64Encoding];
[data base64EncodedStringWithOptions:NSDataBase64Encoding76CharacterLineLength];
If you are still having issues, try out this library: https://github.com/l4u/NSData-Base64
use it like so:
#import "NSData+Base64.h"
NSData *someData //load your data from a file, url or photo as needed
NSData *file = [NSData dataWithContentsOfFile:#"mytextfile.txt"];
NSData *photo = UIImageJPEGRepresentation(self.photo.image,1);
//encode it
NSString *base64string = [photo base64EncodedString];
NSString *base64file = [file base64EncodedString];
//decode it
NSData *back = [NSData dataFromBase64String:base64string];
Try Google's GTMStringEncoding class. You'll need GTMDefines.h too.
GTMStringEncoding *coder = [GTMStringEncoding rfc4648Base64StringEncoding];
NSString *encodedBase64 = [coder encodeString:#"Mary had a little lamb"];
// will contain the original text
NSString *decodedText = [coder decodeString:encodedBase64];
To encode NSData* to NSString* and back to NSData*, use the encode: + decode: methods instead of encodeString: + decodeString:.
As a bonus you get a lot of additional useful encodings, such as the url-safe variant of Base64.

Getting weird characters when going from NSString to bytes and then back to NSString

NSString *message = #"testing";
NSUInteger dataLength = [message lengthOfBytesUsingEncoding:NSUnicodeStringEncoding];
void *byteData = malloc( dataLength );
NSRange range = NSMakeRange(0, [message length]);
NSUInteger actualLength = 0;
NSRange remain;
BOOL result = [message getBytes:byteData maxLength:dataLength usedLength:&actualLength encoding:NSUnicodeStringEncoding options:0 range:range remainingRange:&remain];
NSString *decodedString = [[NSString alloc] initWithBytes:byteData length:actualLength encoding:NSUnicodeStringEncoding];
My issue is that I expect decodedString to be testing, but instead it looks like chinese characters. I thought it could be an issue with null-terminated data, but it seems that that should not be an issue.
You want something like this?
NSString *message = #"testing";
NSData *bytes = [message dataUsingEncoding:NSUTF8StringEncoding];
NSString* messageDecoded = [[NSString alloc] initWithData:bytes encoding:NSUTF8StringEncoding];
NSLog(#"decoded: %#", messageDecoded);
The UTF-16 byte order is getting reversed between the encode and decode.
You can do any one of the following:
Use an encoding that specifies an explicit byte order (e.g., NSUTF16BigEndianStringEncoding, NSUTF16LittleEndianStringEncoding, NSUTF8StringEncoding).
Pass NSStringEncodingConversionExternalRepresentation to the options: parameter in getBytes:maxLength:usedLength:encoding:options:range:. This prepends a byte-order mark to the start of the data.
Use NSData, as Elvis suggested.
These days, UTF-8 is the preferred Unicode encoding in most cases.