How to convert NSData / Data to char array [duplicate] - objective-c

How do you convert an unsigned char array to an NSData in objective c?
This is what I am trying to do, but it doesn't work.
Buffer is my unsigned char array.
NSData *data = [NSData dataWithBytes:message length:length];

You can just use this NSData class method
+ (id)dataWithBytes:(const void *)bytes length:(NSUInteger)length
Something like
NSUInteger size = // some size
unsigned char array[size];
NSData* data = [NSData dataWithBytes:(const void *)array length:sizeof(unsigned char)*size];
You can then get the array back like this (if you know that it is the right data type)
NSUInteger size = [data length] / sizeof(unsigned char);
unsigned char* array = (unsigned char*) [data bytes];

Related

How to convert const char * into a char [] array in objective C [duplicate]

I am trying to convert NSString to char str[]
i have tried this
NSString *data = #"08052678744default0000000";
char mac [[data length]];
strncpy(mac ,[data UTF8String], [data length]);
But got the wrong result.
Your help is urgently needed in resolving this. Thanks
For example:
NSString *data = #"08052678744default0000000";
const char* utf8String = [data UTF8String];
size_t len = strlen(utf8String) + 1;
char mac [len];
memcpy(mac, utf8String, len);
Note the difference between string length and byte length!

Objective-C Equivalent to string.unpack('N') in Ruby

I am trying to convert a string to a 32-bit unsigned, network (big-endian) byte order. I can't seem to figure out how to do this. In Ruby I accomplish this by string.unpack('N') - but can't seem how to manage this in Objective-C. Any suggestions? Thanks!
In Objective-C you would convert NSString to NSData. Then you can access the bytes from the NSData object.
NSString *str = #"😄 H€llö Wòrld";
NSData *data = [str dataUsingEncoding:NSUTF32BigEndianStringEncoding];
NSLog(#"%#", data);
// Output:
// <0001f604 00000020 00000048 000020ac 0000006c 0000006c 000000f6 00000020 00000057 000000f2 00000072 0000006c 00000064>
const uint8_t *bytes = [data bytes]; // pointer to converted bytes
NSUInteger length = [data length]; // number of converted bytes

objective c hmac sha 256 gives wrong nsdata output

So finally figured out how to do an hmac sha 256 hashing. I will be using this for a wcf service api i made. My problem is that the NSData output that my method is sending out have spaces.
eg. This is how it looks like what my API sends out
"2efb00aba01a3f5b674fba3063b43fee7a9356947118......"
And this is how my iphone app shows it
<2efb00ab a01a3f5b 674fba30.....>
This is how my code in objective c looks like:
NSData *hmacSHA256(NSString *key, NSString *data)
{
const char *cKey = [key cStringUsingEncoding:NSASCIIStringEncoding];
const char *cData = [data cStringUsingEncoding:NSASCIIStringEncoding];
unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
return [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
}
This came from this answer:
https://stackoverflow.com/a/8459123/639713
Anyway, my issue is, how do I deal with this. How do I convert the NSdata output to string? And if does get converted to string I'm guessing the output will be different from what the WCF Service API sends out. Do I change how the API processes it's hmacsha256 output?
Thanks!
You could modify your method slightly so that instead of creating an NSData containing the digest bytes, you could create a string formatting the bytes as hexadecimal.
NSString *hmacSHA256(NSString *key, NSString *data)
{
const char *cKey = [key cStringUsingEncoding:NSASCIIStringEncoding];
const char *cData = [data cStringUsingEncoding:NSASCIIStringEncoding];
unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
NSMutableString *result = [NSMutableString string];
for (int i = 0; i < sizeof cHMAC, i++)
{
[result appendFormat:#"%02hhx", cHMAC[i]];
}
return result;
}
<2efb00ab a01a3f5b 674fba30.....> looks like the result of calling -[NSData description], like NSLog would do for any %# format strings. The NSData itself represents a sequence of bytes. The output you're after appears to be the byte sequence as a hexidecimal string. See Best way to serialize an NSData into a hexadeximal string for how to serialize the NSData to that format.

Preparing NSData to store Hex Value. integer constant is too large for its type

Very basic Question. :(. I have a hex value and trying to accommodate into NSData, and
tried the following.
unsigned char bytes [] = {0x0f0121dd06a2d00503040705aa010ba2d0a2d0};
NSData *data = [NSData dataWithBytes: bytes length:19];
NSLog (#" DAta is %# ", data);
I m getting the following Warning
34:37: warning: integer constant is too large for its type
34: warning: large integer implicitly truncated to unsigned type
Data is printed like:
NSDataExample[36136:707] DAta is <d028e08c 7fff7f00 00000000 00000000 0008fc>
I m not sure if i m doing it in a right way?. Kindly advice.
You aren't assigning the char array properly it seems; because it is too large for the type you're assigning. How about this, as an example:
#import <Foundation/Foundation.h>
int main(int argc, char *argv[]) {
NSAutoreleasePool *p = [[NSAutoreleasePool alloc] init];
// your example has longer hex value, truncated here for clarity...
unsigned char bytes[] = { 0x0F, 0x01, 0x21};
NSData *data = [NSData dataWithBytes:bytes length:3];
NSLog (#" Data is %# ", data);
[p release];
}
Prints 2012-11-19 06:40:07.581 Untitled 2[12472:707] Data is <0f0121> to the console
Or, if your hex bytes are in the form of a string, something like this:
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
#autoreleasepool {
NSString *hexString = #"0x0f0121dd06a2d00503040705aa010ba2d0a2d0";
NSMutableData *data = [[NSMutableData alloc] init];
NSRegularExpression *expression = [NSRegularExpression regularExpressionWithPattern:#"[A-Fa-f0-9]{2}" options:0 error:NULL];
[expression enumerateMatchesInString:hexString options:0 range:NSMakeRange(0, hexString.length) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
int hex = (int)strtol([[hexString substringWithRange:result.range] UTF8String], NULL, 16);
printf("hex = %d\n",hex);
[data appendBytes:&hex length:1];
}];
NSLog(#"%s - data = %#",__FUNCTION__,data);
}
return 0;
}
Which prints 2012-11-19 06:56:15.753 TestHexStringToBytes[12891:303] main - data = <0f0121dd 06a2d005 03040705 aa010ba2 d0a2d0> to the console.
That's too large, you are using a char array but the array just contains one character, that gets truncated so you don't need an array.
But even using a long unsigned int there isn't enough memory to store this value.Use memset instead, and calculate the value of each byte.

how convert [NSData length] to a NSData

ex:
NSData *data = [NSData dataWithContentsOfFile:filePath];
int len = [data length];
if len = 10000,
i hope i can convert 1000 to a NSData look like
char hoperesult[] = {0x10, 0x27, 0x00, 0x00}
and hoperesult[] must always 4 Bytes
So you want the length in 4 little-endian bytes, correct? I think this will do it:
unsigned int len = [data length];
uint32_t little = (uint32_t)NSSwapHostIntToLittle(len);
NSData *byteData = [NSData dataWithBytes:&little length:4];
(Note that most network protocols use big-endian, but you showed little-endian so that's what this does.)
I'm not 100% sure what you mean here, but I think you are attempting to fill hoperesult with the values found in the file at 'filePath'.
struct _hoperesult {
char data[4];
} *hoperesult;
NSData *data = [NSData dataWithContentsOfFile:filePath];
NSUInteger len = [data length];
NSRange offset;
offset.location = 0;
offset.length = sizeof(_hoperesult);
NSData *hoperesultData;
while( (offset.location + offset.length) < len ) {
hoperesultData = [data subdataWithRange:offset];
// the equivalent of your char hoperesult[] content...
hoperesult = [hoperesultData bytes]
}
An instance of NSData can return a pointer to the actual bytes of data using the "bytes" method. It returns a (const void *). You could in theory simply cast [data bytes] to a char * and use the offset directly; or you can do like in the above code and return smaller chucks of NSData.
Hope that helps!