How can I convert NSData to C string? - ios

How can I convert [NSString dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES] result to C string?
Returns an NSData object containing a representation of the receiver encoded using a given encoding.
- (NSData *)dataUsingEncoding:(NSStringEncoding)encoding allowLossyConversion:(BOOL)flag
Note that the data returned by dataUsingEncoding:allowLossyConversion:
is not a strict C-string since it does not have a NULL terminator.

NSMutableData *data = [[#"foo" dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES] mutableCopy];
char nul = '\0';
[data appendBytes:&nul length:sizeof(nul)];
const char *cString = [data bytes];
Or, simply:
const char *cString = [#"foo" UTF8String];
... with exactly the same result.

There is an -[NSString cStringUsingEncoding:] method that sounds promising.

It seems that you are asking the wrong question.
NSString* myString = #"Whatever";
const char* utf8String = [myString UTF8String];
Quite pointless to go through NSData.

Related

How can I hash a NSString to SHA512

I have one quick question...
I am building a social media network site app and I need to hash the password NSString. How would I accomplish this? I have the password field on the app and would like to hash the string and encode it in SHA512 for the POST request.
Thanks in advance,
TechnologyGuy
Already answered: hash a password string using SHA512 like C#
But here's the copy-pasted code:
#include <CommonCrypto/CommonDigest.h>
+ (NSString *) createSHA512:(NSString *)source {
const char *s = [source cStringUsingEncoding:NSASCIIStringEncoding];
NSData *keyData = [NSData dataWithBytes:s length:strlen(s)];
uint8_t digest[CC_SHA512_DIGEST_LENGTH] = {0};
CC_SHA512(keyData.bytes, keyData.length, digest);
NSData *out = [NSData dataWithBytes:digest length:CC_SHA512_DIGEST_LENGTH];
return [out description];
}
Or if you prefer a hashed output, try this:
+(NSString *)createSHA512:(NSString *)string
{
const char *cstr = [string cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:string.length];
uint8_t digest[CC_SHA512_DIGEST_LENGTH];
CC_SHA512(data.bytes, data.length, digest);
NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA512_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_SHA512_DIGEST_LENGTH; i++)
[output appendFormat:#"%02x", digest[i]];
return output;
}
+ (NSData *)sha512:(NSData *)data {
unsigned char hash[CC_SHA512_DIGEST_LENGTH];
if ( CC_SHA512([data bytes], [data length], hash) ) {
NSData *sha1 = [NSData dataWithBytes:hash length:CC_SHA512_DIGEST_LENGTH];
return sha1;
}
return nil;
}
Put this in a category on NSData, or use it whatever way you like, the code remains the same.
You should've researched your question. I found an answer in one google search.

Trouble converting NSData to int

I have an NSData object that contains just <64> which is supposed to represent the int 100
How can I convert this NSData to an int?
I can convert it to it's Chr equivalent d using
NSString *string = [[NSString alloc] initWithData:characteristic.value encoding:NSUTF8StringEncoding];
but I need the Dec equivalent of 100
Thanks
<64> means that the NSData object contains a single byte with the value 0x64 = 100,
so the following should work;
const uint8_t *bytes = [data bytes]; // pointer to the bytes in data
int value = bytes[0]; // first byte
int *b = (int *)data.bytes;
printf("%d",*b); //prints 100
Below logic converts NSData to integer perefctly. Length of bytes does not matter. It just works.
NSData *data;
NSString *stringData = [data description];
stringData = [stringData substringWithRange:NSMakeRange(1, [stringData length]-2)];
unsigned dataAsInt = 0;
NSScanner *scanner = [NSScanner scannerWithString: stringData];
[scanner scanHexInt:& dataAsInt];

SHA1 for Specific String in iOS

According to my requirement:
The input string has to be converted into Byte Values.
Each character of string , which are 16 bit values , has to be converted to low 8 bits.
The Sha1 is then computed over the byte Array.
The resulting SHA-1 is converted into a 40 character string.
I know how to convert a string into SHA1 , but the rest of part is a bit gloomy to me.
I have been able to do the last two steps.
unsigned char digest[CC_SHA1_DIGEST_LENGTH];
NSData *dataString = [yourString dataUsingEncoding: NSUTF8StringEncoding];
if (CC_SHA1([dataString bytes], [dataString length], digest)) {
//Sha1 is calculated & stored in digest.
}
Any help will be appreciated.
I have created this function , which works fine according to your requirement . You just have to input a string.
#import <CommonCrypto/CommonDigest.h>
- (NSString *)calculateSHA:(NSString *)yourString
{
const char *ptr = [yourString UTF8String];
int i =0;
int len = strlen(ptr);
Byte byteArray[len];
while (i!=len)
{
unsigned eachChar = *(ptr + i);
unsigned low8Bits = eachChar & 0xFF;
byteArray[i] = low8Bits;
i++;
}
unsigned char digest[CC_SHA1_DIGEST_LENGTH];
CC_SHA1(byteArray, len, digest);
NSMutableString *hex = [NSMutableString string];
for (int i=0; i<20; i++)
[hex appendFormat:#"%02x", digest[i]];
NSString *immutableHex = [NSString stringWithString:hex];
return immutableHex;
}
Then you just have to call the above method.
[self calculateSHA:yourString];
NSData *dataString = [yourString dataUsingEncoding: NSUTF8StringEncoding];
converts the string to UTF-8 bytes, e.g. "é" = Unicode 00E9 is converted to the two bytes C3 A9, and "€" = Unicode 20AC is converted to three bytes E2 82 AC.
If your requirement is to "truncate" the Unicode characters to the lower 8 bits, you have to do this "manually", I do not know a built-in encoding that could be used for that:
NSMutableData *dataString = [NSMutableData dataWithLength:[yourString length]];
uint8_t *dataBytes = [dataString mutableBytes];
for (NSUInteger i = 0; i < [yourString length]; i++) {
// assigning the character to a uint_8 truncates to the lower 8 bit:
dataBytes[i] = [yourString characterAtIndex:i];
}
Based on your code snippet, you want to do something like:
unsigned char digest[CC_SHA1_DIGEST_LENGTH];
NSData *dataString = [yourString dataUsingEncoding: NSUTF8StringEncoding];
NSMutableString *outString;
if (CC_SHA1([dataString bytes], [dataString length], digest)) {
for (int i=0;i<CC_SHA1_DIGEST_LENGTH;i++) {
[outString appendFormat:#"%02x", digest[i]];
}
}
Where outString will be your 40-char string.
Here's an NSString category for creating a SHA1 hash of an NSString.
Creating SHA1 Hash from NSString

Having an issue in encrypting/decrypting field in SQLite3

I am trying to encrypt/decrypt one field of SQLite3 database stored in iPhone app.
I am using this category mentioned in this question.
While encrypting, I am using following code:
NSString *key = #"pass123";
NSString *secret = webNote.note;
NSData *plain = [secret dataUsingEncoding:NSUTF8StringEncoding];
NSData *cipher = [plain AES256EncryptWithKey:key];
sqlite3_bind_text(statement, 1, [[cipher description] UTF8String], -1, SQLITE_TRANSIENT);
It does save data into the field in 74657874 20746f20 656e6372 797074 format.
But while decrypting, I get blank field (tried everything I knew). I am using following code for decrypting:
char *noteDet = (char *)sqlite3_column_text(statement, 1);
NSString *key = #"pass123";
NSString *secret = [NSString stringWithUTF8String:noteDet];
NSData *secretData = [secret dataUsingEncoding:NSUTF8StringEncoding];
NSData *clean = [secretData AES256DecryptWithKey:key];
aNote.note = ([[NSString alloc] initWithData:clean encoding:NSUTF8StringEncoding])?[[NSString alloc] initWithData:clean encoding:NSUTF8StringEncoding]:#"";
I think, I am unable to convert types. Please guide!
Thanks!
The description of NSData returns something like "" => if you were to read that again you would get different overall data ( and of a higher length ), also you are right that you are not converting the data types correctly.
Try saving the NSData object directly, by saving the bytes themselves rather than the description of the NSData object.
void *bytes = [dataObject bytes];
size_t length = [dataObject length];

NSString cString is Deprecated. What is the alternative?

I've got another newbie question.
I've written a piece of code that converts a NSString to NSMutableData in order to simulate a webService result.
It turns out however that cString is deprecated. Can you help me replace it?
Here's my code.
NSString *testXMLDataString =
#"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
etc....
"</SOAP-ENV:Envelope>";
//Replace webData Received from the web service with the test Data
NSMutableData *testXMLData = [NSMutableData dataWithBytes:[testXMLDataString cString] length:[testXMLDataString length]];
[webData setData:testXMLData];
Get the raw bytes from the string.
Get the length of those bytes in the UTF8 encoding.
Create the NSData object using the +dataWithBytes:length: method.
const char *rawBytes = [testXMLDataString UTF8String];
const NSUInteger length = [testXMLDataString lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
NSAssert(length > 0, #"Couldn't convert to UTF-8");
NSMutableData *testXMLData = [NSMutableData dataWithBytes:rawBytes length:length];
[webData setData:testXMLData];

Resources