Increasing Length of NSData - objective-c

Basically, I have an NSString of 46 characters which i convert to NSData. I need to pad the string to 48 characters. It does not work via just adding ' ' to the end of the NSString. So, i just increased the length of NSData using this:
NSString *string = #"__46characterlongstring__";
NSData *d = [string dataUsingEncoding:NSUTF8StringEncoding];
NSLog(#"d: %#", d);
NSData *data = [NSData dataWithBytes:[d bytes] length:48];
NSLog(#"data: %#", data);
The NSData called 'd' returns <723d6c67 6e267573 65726e61 6d653d64 61766964 77617473 6f6e3936 26706173 73776f72 643d736e 30307079 6f32>
The NSData called 'data' returns <723d6c67 6e267573 65726e61 6d653d64 61766964 77617473 6f6e3936 26706173 73776f72 643d736e 30307079 6f32_>, where _ is 4 random characters (usually numbers)
How can i make sure that 'data' returns <723d6c67 6e267573 65726e61 6d653d64 61766964 77617473 6f6e3936 26706173 73776f72 643d736e 30307079 6f320000> - 4 0's instead of 4 random characters?
Thanks.

You want to use an NSMutableData, which you make from the NSData you get back from the string, then add some zeros:
NSMutableData *paddedData = [NSMutableData dataWithData:d];
[paddedData increaseLengthBy:4];

Related

Convert NSData object to NSString format

I am getting something like this in NSData and I want to print it as NSString Data, So can I get some solutions for this.
My data is
(<30820605 308204ed a0030201 02021011 b5aff6d9 6c725e0d 33105e6c
6115a930 0d06092a 864886f7 0d01010b 05003044 310b3009 06035504
06130255 53311630 14060355 040a130d 47656f54 72757374 20496e63
2e311d30 1b060355 04031314 47656f54 72757374 2053534c 20434120
2d204733 301e170d 31363032 30333030 30303030 5a170d31 37303230
32323335 3935395a 30818431 0b300906 03550406 1302494e 3110300e
06035504 08130748 61727961 6e613110 300e0603 55040714 07477572
67616f6e 31243022 06035504 0a141b50 726f7469 6e757320 496e666f
74656368 20507674 2e204c74 642e3115 30130603 55040b14 0c50726f
64756374 20546561 6d311430 12060355 0403140b 2a2e7472 75706179
2e696e30 82012230 0d06092a 864886f7 0d010101 05000382 010f0030
82010a02 82010100 b561a9fa 80f7e7f7 c9e64b02 05259a84 c73682d6
b3feee24 cbf04511 18667669 52f62331 a1056106 595b22fb db63cc4b
c700e90f 0a1d24cb ea8f253c 3d7c8a57 5abd8f86 62c4e866 bbd0ace9
2c2eef5a 30046e48 a83d374b ef8f8170 cfa703d3 0099ff45 559031f8
53e8a67d af6552c2 4ff628c3 9979e3e0 62a5cc9a d73cb5fa a3ef6a45 )
This same data I want in string format.
I am using this piece of code
NSString *myString = [NSString stringWithUTF8String:[remoteCertificateData bytes]];
But I am getting nil for myString.
You can use,
NSString* newStr = [[NSString alloc] initWithData:theData
encoding:NSUTF8StringEncoding];
If the data is null-terminated, you should instead use
NSString* newStr = [NSString stringWithUTF8String:[theData bytes]];
If NSData is not UTF-8-encoded, you will get nil.
for further reference see these links:
please have look on this.
NSData bytes to string
You can use following Code Snippet to convert NSData into NSString :
NSString* str = [[NSString alloc] initWithData:aNSData encoding:NSUTF8StringEncoding];
You don't need to match string. Just convert the string in NSData like:
NSData* data = [str dataUsingEncoding:NSUTF8StringEncoding];
then compare NSData.

char* to NSData issue

I am trying to write a function that takes char* as an input parameter and will serialize it into JSON.
I am running into an issue with converting the input parameter, options to NSData. I used the following line of code:
NSData *data = [NSData dataWithBytes:options length:sizeof(options)];
This did not work. A different set of code did work:
NSString* stringFromChar = [[NSString alloc] initWithUTF8String:options];
NSData * data = [stringFromChar dataUsingEncoding:NSUTF8StringEncoding];
I am curious about why it was necessary to convert my code from char* to an NSString and then to NSData and why I could not do that directly. Is there a way to directly convert char* to NSData without this intermediary step? Thanks.
As the comments indicated, sizeof(options) where options is a char * will produce the size of the pointer, not the length of the string. Also pointed out in comments, strlen(options) counts characters up to the first 0x0, which is what you want...
NSData *data = [NSData dataWithBytes:options length:strlen(options)];
// options must be null-terminated

carriage return for encoding

Im trying to send ascii encoded message to a server. My problem is coming in when I try to append the carriage return to the string
-(void)button2Pressed
{
NSMutableString *mutableString = [NSMutableString stringWithString:#"h323name get"];
[self sendStringCommand:mutableString];
}
-(void)sendStringCommand:(NSMutableString*)string
{
[string appendString:#"\\r"];
NSLog(#"string %# wtf",[string dataUsingEncoding:NSASCIIStringEncoding]);
NSData * testData = [[NSData alloc]initWithBytes:[string dataUsingEncoding:NSASCIIStringEncoding] length:sizeof([string dataUsingEncoding:NSASCIIStringEncoding])];
[socket writeData:testData withTimeout:20 tag:1];
}
currently this outputs this:
string <68333233 6e616d65 20676574 5c72> wtf
which should be
string <68333233 6e616d65 20676574 0d> wtf
Just plain /r did a new line hence the wtf characters after the data in the nslog
You have too many backslashes. Try this:
[string appendString:#"\r"];
Also, your creation of testData is completely wrong. The way you are creating testData is passing a pointer to an NSData object as the "bytes" parameter, and passing the size of a pointer to an NSData as the "length" parameter. You should just do this:
NSData *testData = [string dataUsingEncoding:NSASCIIStringEncoding];

Converting NSData bytes to NSString

I am trying to create a 16 byte and later 32 byte initialization vector in objective-c (Mac OS). I took some code on how to create random bytes and modified it to 16 bytes, but I have some difficulty with this. The NSData dumps the hex, but an NSString dump gives nil, and a cstring NSLog gives the wrong number of characters (not reproduced the same in the dump here).
Here is my terminal output:
2012-01-07 14:29:07.705 Test3Test[4633:80f] iv hex <48ea262d efd8f5f5 f8021126 fd74c9fd>
2012-01-07 14:29:07.710 Test3Test[4633:80f] IV string: (null)
2012-01-07 14:29:07.711 Test3Test[4633:80f] IV char string t^Q¶�^��^A
Here is the main program:
int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
//NSString *iv_string = [NSString stringWithCString:iv encoding:NSUTF8StringEncoding];
testclass *obj = [testclass alloc];
NSData *iv_data = [obj createRandomNSData];
//[iv_string dataUsingEncoding:NSUTF8StringEncoding];
NSLog(#"iv hex %#",iv_data);
//NSString *iv_string = [[NSString alloc] initWithBytes:[iv_data bytes] length:16 encoding:NSUTF8StringE$
NSString *iv_string = [[NSString alloc] initWithData:iv_data encoding:NSUTF8StringEncoding];
NSLog(#"IV string: %#",iv_string);
NSLog(#"IV char string %.*s",[iv_data bytes]);
return 0;
]
(I left in the above some commented code that I tried and did not work also).
Below is my random number generater, taken from a stack overflow example:
#implementation testclass
-(NSData*)createRandomNSData
{
int twentyMb = 16;
NSMutableData* theData = [NSMutableData dataWithCapacity:twentyMb];
for( unsigned int i = 0 ; i < twentyMb/4 ; ++i )
{
u_int32_t randomBits = arc4random();
[theData appendBytes:(void*)&randomBits length:4];
}
NSData *data = [NSData dataWithData:theData];
[theData dealloc];
return data;
}
#end
I am really quite clueless as to what could be the problem here. If I have data as bytes, it should convert to a string or not necessarily? I have looked over the relevant examples here on stackoverflow, but none of them have worked in this situation.
Thanks,
Elijah
An arbitrary byte sequence may not be legal UTF8 encoding. As #Joachim Isaksson notes, there is seldom reason to convert to strings this way. If you need to store random data as a string, you should use an encoding scheme like Base64, serialize the NSData to a plist, or similar approach. You cannot simply use a cstring either, since NULL is legal inside of a random byte sequence, but is not legal inside of a cstring.
You do not need to build your own random byte creator on Mac or iOS. There's one built-in called SecRandomCopyBytes(). For example (from Properly encrypting with AES with CommonCrypto):
+ (NSData *)randomDataOfLength:(size_t)length {
NSMutableData *data = [NSMutableData dataWithLength:length];
int result = SecRandomCopyBytes(kSecRandomDefault,
length,
data.mutableBytes);
NSAssert(result == 0, #"Unable to generate random bytes: %d",
errno);
return data;
}
When converting NSData to NSString using an UTF8 encoding, you won't necessarily end up with the same number of bytes since not all binary values are valid encodings of characters. I'd say using a string for binary data is a recipe for problems.
What is the use of the string? NSData is exactly the datatype you want for storing binary data to begin with.

Why does this NSString created from an NSData object fail to show it has contents?

Why does the following code produce the logging at the bottom ?
Here is the anomaly- my second NSLog should print the chrStr but produces nothing, empty, which is verified by this debug command:
(gdb) po chrStr
object returns empty description
However, the third NSString where I re-convert the NSString back to NSData object DOES display the the data, the same value as in the first NSLog, as it should. This would indicate to me that chrStr must have actual contents. But it seems not to be so from the NSLOG or the po command. Why ?
NSString *login;
NSString *pass;
// Purpose: NSString *loginString = [NSString stringWithFormat:#"\000%#\000%#", login, pass];
login = #"Loginname"; // text string1
pass = #"Password"; // text string2
// convert text strings to data objects
NSData *subData1 = [login dataUsingEncoding:NSUTF8StringEncoding];
NSData *subData2 = [pass dataUsingEncoding:NSUTF8StringEncoding];
// embed a NULL into new NSData object
NSMutableData *data = [NSMutableData data];
unsigned char zeroByte = 0;
[data appendBytes:&zeroByte length:1];
// append string1, NULL, string2 to data object
[data appendData:subData1];
[data appendBytes:&zeroByte length:1];
[data appendData:subData2];
NSLog(#"1.NSData: %#", data); // print data object
// create a character string from data object
NSString *chrStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"2.NSString: %#", chrStr); // print character string
// create data object from string object
NSData *chrData = [chrStr dataUsingEncoding:NSUTF8StringEncoding];
NSLog(#"3.NSDATA: %#", chrData); // print data object
Produces:
[1071:207] 1.NSData: 004c6f67 696e6e61 6d650050 61737377 6f7264
[1071:207] 2.NSString:
[1071:207] 3.NSDATA: 004c6f67 696e6e61 6d650050 61737377 6f7264
This is a real mystery to me. If chrStr is empty then 3-NSDATA could not display its info, but it does !
What am I trying to accomplish ? Well, check my very first comment line: // purpose:
That line when uncommented produces a warning, even though it actually works, so I was trying to do it another way that allowed me to have a clean compile. If you see a better way to accomplish that objective, I all eyes and ears. But please don't dwell on why that #"\000%#\000%#" string is necessary, start out accepting that it is. Thanks.
In C (and therefore objective-c), a null byte is used to represent the end of a string. When you create the string object, it takes all of the data you have given it without parsing, which is why you can convert it back to data successfully. However, when you display the string, the system reads the string up to the first null byte, which is the first byte. Therefore, the string contains data, but any system functions which read byte by byte instead of using the strings returned length will think it is empty. When you work with non-displayable characters, you should try to use data objects over string objects as often as possible.