Converting floats to NSData and back in Objective-C - iphone

In an iphone application, I'm looking to convert a float to NSData for it to be sent over bluetooth and then converted back again when it's received. I have the bluetooth part working fine, but when I use this to convert to NSData:
NSData *data = [[NSData alloc]init];
float z = 9.8574; // Get the float value, 9.8574 is just an example
[data getBytes:&z length:sizeof(float)];
I can not convert it back to a float. I've tried a couple of methods but I'm wondering if this is the correct way to encode the float to NSData??
Thanks

Here is how to encode and decode a float with NSData:
encoding:
NSMutableData * data = [NSMutableData dataWithCapacity:0];
float z = ...;
[data appendBytes:&z length:sizeof(float)];
decoding:
NSData * data = ...; // loaded from bluetooth
float z;
[data getBytes:&z length:sizeof(float)];
A couple of things to note here:
1. You have to use NSMutableData if you are going to add things to the data object after creating it. The other option is to simply load the data all in one shot:
NSData * data = [NSData dataWithBytes:&z length:sizeof(float)];
2. the getBytes:length: method is for retrieving bytes from an NSData object, not for copying bytes into it.

Related

Saving a uint8_t ciphertext into DataModel

I am building a simple iphone (SDK6.1) application that encrypts some user's notes, stores the into a database and when user enters a password (does not need to be encrypted) it will decrypt his notes and show them to him.
For the database i am using Core Data (.xcdatamodel). The encrypted text at the moment is declared as String in the data model and in the Notes.h fil,e it is declared as NSString.
For the Encryption i am using apple's sample code from CryptoExercise which works perfectly.
The problem is that when i try to save the encrypted text in the database and then decrypt it i am not getting the desired results.. basically i am getting an empty string back.
Obviously i am using the following code to convert from uint8_t to NSString so i can store it into the data model and i understand that this is my main problem.
uint8_t *cipherBuffer = NULL;
SecKey *encrypt = [[SecKey alloc]init];
NSString *et = [[NSString alloc]init];
[encrypt generateKeyPairRSA];
// Encrypt the plain text
cipherBuffer = [encrypt Encryption:plainTextField.text];
// Convert uint8_t to NSString
NSMutableData *data = [[NSMutableData alloc]init];
[data appendBytes:cipherBuffer length:strlen((char*)cipherBuffer)+1];
NSString *string = [[NSString alloc]initWithData:data encoding: NSASCIIStringEncoding];
// Save to Data Model
[self.currentNote setEncryptedText:string];
[self.delegate addNewNoteViewControllerDidSave];
// Retrieve encrypted text from database
et = [self.currentNote encryptedText];
// Convert back to uint_8
NSData *someData = [et dataUsingEncoding:NSUTF8StringEncoding];
const void *bytes = [someData bytes];
uint8_t *crypto_data = (uint8_t*)bytes;
// Decrypt Data
[encrypt Decryption:crypto_data];
As i said before i understand that converting uint8_t is the main problem here and i would like to know which is the correct way to do this?
Is it possible with Data Model at all, or should i go to SQLite??
You cannot convert arbitrary bytes sequences to NSString and back like that. For example,
if data contains the single byte 128 (hex 0x80), then
NSString *string = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
creates a string with one Unicode character U+0080. When you convert this back to NSData with
NSData *d1 = [string dataUsingEncoding:NSUTF8StringEncoding];
then d1 will contain the bytes 0xC2 0x80 (which is the UTF-8 for U+0080). But
NSData *d2 = [string dataUsingEncoding:NSASCIIStringEncoding];
does also not work (d2 = nil), because the string cannot be converted to 7-bit
ASCII.
So you should either
store the encrypted data as "Binary Data" in Core Data, or
store the encrypted data as String, but choose a different conversion strategy,
for example Base64.
So just to answer the question so i can use code and everything..
I changed the EncryptedText in the Data Model to Binary Data and then the code would look like this:
uint8_t *cipherBuffer = NULL;
SecKey *encrypt = [[SecKey alloc]init];
[encrypt generateKeyPairRSA];
cipherBuffer = [encrypt Encryption:plainTextField.text];
NSMutableData *data = [[NSMutableData alloc]init];
[data appendBytes:cipherBuffer length:strlen((char*)cipherBuffer)+1];
// Save cipher into the Data Model
[self.currentNote setEncryptedText:data];
[self.delegate addNewNoteViewControllerDidSave];
// Retrieve cipher back from Data Model
NSData *etData = [[NSData alloc]init];
etData = [self.currentNote encryptedText];
// Convert back to uint8_t
const void *bytes = [etData bytes];
uint8_t *crypto_data = (uint8_t*)bytes;
// De cypher
[encrypt Decryption:crypto_data];

Appending NSData

Can anyone help me with appending the nsdata
i have NSData as encrypted data
<a5ecaf36 15519fcb cd164cf6 a83eaf55 367f1109 b6898951 2c227b86 ed98d0a6 db2d7a8a 25086baf 58436328 2583ed78 ef3410e5 4507d8a4 40fe22f9 0538a67c 065fbb8e ad445041 56f3ea87 e7b73189 aa0b8c66 a9da381e 6f718583 dce57b9a f2f5d9c9 b336c92f b2df2d43 9083bd1d e33e907b 7fd0fdc7 e5f64db9 b7f0975a>
i want to add F8 to this and send it to server as NSData
NSMutableData *mData = [NSMutableData dataWithData:mData];
unsigned char f8[1] = 0xF8;
[mData appendBytes:f8 length:1];
// You can use the mutable data as is or turn it back into a non-mutable object:
data = [NSData dataWithData:mData];

Converting the Cipher Buffer to nsdata and back to cipherBuffer

My problem is CipherBuffer which is uint8_t i am not able to convert that to NSData and get back the same value.the thing is i need to send the encrypted data to server.
Even i get NSData from serverside and i need to convert that to (unit8_t *). Is their a way to do that i am using below method to decrypt
- (void)decryptWithPrivateKey:(uint8_t *)cipherBuffer plainBuffer:(uint8_t *)decryptedBuffer
To convert uint8_t to NSData
NSData *data = [NSData dataWithBytes:(const void *)encrypted length:bufferSize];
And to convert NSData to uint8_t you can try below method of NSData
- (const void *)bytes;

how to convert NSData to Binary data?

I need convert NSData to Binary data for send to php server
You don't need to convert NSData. Just set the post body of the NSMutableURLRequest.
const void *p = [nsDataObject bytes];
NSUInteger length = [nsDataObject length];

A question relted to NSMUtabledata

NSDATA *data1;
NSDATA *data2;
NSDATA *data3;
I want to convert my this all 3 data's to bytearray and then again i want to append it to the
NSMutabledata;
What Should I do For that?
There is no need to convert them to a byte array.
NSMutableData *md = [NSMutableData dataWithData:data1];
[md appendData:data2];
[md appendData:data3];
will give you the data in md.