"implicit declaration of function" error in Objective-C - iphone

i want to convert a short string to md5 hash , I found several post about it but noone worked.
it's the simplest example that I found . i have this error
implicit declaration of function CC_MD5 is invalid in C99
- (NSString *) md5:(NSString *) input
{
const char *cStr = [input UTF8String];
unsigned char digest[16];
CC_MD5( cStr, strlen(cStr), digest ); // This is the md5 call
NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
[output appendFormat:#"%02x", digest[i]];
return output;
}
UPDATE
i added #import , it work fine when i call the method like this :
[self md5:#"admin"];
, i get the right md5 hash. But when i do this
[self md5:userId];
i get an error ,
[NSDecimalNumber UTF8String]: unrecognized selector sent to instance
0x4d3e280
But userId is not decimal , he contain facebook id , but it's declared as NSString
NSString *userId;
#property(retain,nonatomic) NSString *userId;

Because the declaration of CC_MD5 has not been seen.
Include the security framework in your project and
#import <CommonCrypto/CommonDigest.h>

You need to include the CommonDigest Header file from the Crypto library at the top of your class where the MD5 function is defined as well as include the Security Framework
#import <CommonCrypto/CommonDigest.h>

Are you importing the right interface that defines CC_MD5?
#import "CommonDigest.h"

Related

NSString custom md5 class method warning:

I have done I custom class method for NSString to md5 a NSString.
This is my code:
NSString+CustomMethod.h
#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonDigest.h>
#interface NSString (CustomMethod)
+ (NSString*)MD5:(NSString *)string;
#end
NSString+CustomMethod.m
#import "NSString+CustomMethod.h"
#implementation NSString (CustomMethod)
+ (NSString*)MD5:(NSString *)string
{
// Create pointer to the string as UTF8
const char *ptr = [string UTF8String];
// Create byte array of unsigned chars
unsigned char md5Buffer[CC_MD5_DIGEST_LENGTH];
// Create 16 byte MD5 hash value, store in buffer
CC_MD5(ptr, strlen(ptr), md5Buffer);
// Convert MD5 value in the buffer to NSString of hex values
NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
[output appendFormat:#"%02x",md5Buffer[i]];
return output;
}
#end
This Methodclass works great, but compiler give me a warring:
warning: class method '+MD5:' not found (return type defaults to 'id') [3]
How can I remove this warning ??
PS: if a put #import "NSString+CustomMethod.h" no warning is shown, but it's a workAround, I have created a custom method class not to include my custom class everywhere I need it
Thanks for any helps !!
Put #import "NSString+CustomMethod.h" in .pch file or in file where you want to use it.

How do I create a hash of a file on iOS?

I'm trying to create unique file names by renaming them using their hashed value in iOS. How can I do that?
you could achieve this by extending NSString,
Try this in your .h:
#interface NSString(MD5)
- (NSString *)generateMD5Hash
#end
and this in your .m
- (NSString*)generateMD5Hash
{
const char *string = [self UTF8String];
unsigned char md5Buffer[CC_MD5_DIGEST_LENGTH];
CC_MD5(string, strlen(string), md5Buffer);
NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
[output appendFormat:#"%02x",md5Buffer[i]];
return output;
}
you can implement this by making a new class called NSString+MD5, and inserting the code above in the corresponding files (.h and .m)
EDIT: Do not forget to import
< CommonCrypto/CommonDigest.h >
EDIT 2:
And for NSData;
#interface NSData(MD5)
- (NSString *)generateMD5Hash;
#end
your .m:
- (NSString *)generateMD5Hash
{
unsigned char md5Buffer[CC_MD5_DIGEST_LENGTH];
CC_MD5(self.bytes, (CC_LONG)self.length, md5Buffer);
NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
[output appendFormat:#"%02x",md5Buffer[i]];
return output;
}
Please note that the value returned is autorelease and might need to be retained by the receiver.
Hope this helps.
Why don't you simply generate unique identifiers and use it? like
CFUUIDRef uuidObj = CFUUIDCreate(nil);
NSString *uniqueId = (NSString*)CFUUIDCreateString(nil, uuidObj);
CFRelease(uuidObj);
NSLog(#"%#",uniqueId);
[uniqueId autorelease];
Using NSData is an expensive choice. Better use NSFileHandler extension if you are dealing with big files anytime.

objective c: passing a char argument to function crashes the app

I wrote a singleton called SomeValues where I initialize a foo NSMutableArray. I then tried to write a function SetBFSV to set the values of this array from different control views.
#interface SomeValues : NSObject {
NSMutableArray *foo;}
+ (SomeValues *) sharedInstance;
#implementation
...
- (void) SetBFSV:(char)lbl ToVal:(long)BFSvl{
NSNumber *ValueBFSvl = [NSNumber numberWithLong:BFSvl];
NSString *Strlbl = [[NSString alloc] stringWithFormat:#"%s",lbl];
[foo setValue:ValueBFSvl forKey:Strlbl];
}
I know that setValue requires a NS object for both the value and the key, but I cannot declare my function as
(void) SetBFSV:(NSString)lbl ToVal:(NSNumber)BFSvl
because it doesn't compile with the error: "Can not use an object as parameter to a method".
In one ControlView I wrote then this piece of code:
SomeValues *myBFSV = [SomeValues sharedInstance];
const unsigned char *Bar = (unsigned char *)[#"Label1" UTF8String];
NSLog(#"The string %s", Bar);
[myBFSV SetBFSV:Bar ToVal:2.5];
When compiling I get a warning on the last line:
warning: passing argument 1 of 'SetBFSV:ToVal:' makes integer from pointer without a cast
Which integer? I'm getting stupid looking around for it. When running I get the print out from the NSLog, but right afterwards the program obviously crashes with this error:
'NSInvalidArgumentException', reason: '-[NSPlaceholderString stringWithFormat:]: unrecognized selector sent to instance 0x4e03280'
Clearly I'm passing something wrong to stringWithFormat but I cannot understand what.
Thanks for any help. Have a nice day!
/luca
Possible problems with your code (unless you have typos in it):
- (void) SetBFSV:(char)lbl ToVal:(long)BFSvl function expects char as its 1st parameter but you pass it a char* - your 1st warning probably comes from here
stringWithFormat is a class method so your code should look either:
NSString *Strlbl = [[NSString alloc] initWithFormat:#"%s",lbl];
[foo setValue:ValueBFSvl forKey:Strlbl]
or
NSString *Strlbl = [NSString stringWithFormat:#"%s",lbl];
[foo setValue:ValueBFSvl forKey:Strlbl]
since you try to use -stringWithFormat instead of +stringWithFormat you get a crash
If you pass char to a function then correct format specifier for it will be %c, not %s
You probably must release your Strlbl variable if you create it with alloc/init otherwise it will leak (but you must not release it if you use +stringWithFormat:)
For one, you can't use an object as a paramter:
(void) SetBFSV:(NSString)lbl ToVal:(NSNumber)BFSvl
You need to pass them as pointers, using the asterisk.
(void) SetBFSV:(NSString*)lbl ToVal:(NSNumber*)BFSvl
Furthermore, if you need to pass them as (char) and (long) your bit of code:
SomeValues *myBFSV = [SomeValues sharedInstance];
const unsigned char *Bar = (unsigned char *)[#"Label1" UTF8String];
NSLog(#"The string %s", Bar);
[myBFSV SetBFSV:Bar ToVal:2.5]; // in either case, this is a long. why are you passing a double here?
Passes *Bar as a pointer. You should really read up on the pointers and objects. IF you need to pass them in as (const char*) and (long) do it like this:
- (void) SetBFSV:(const char*)lbl ToVal:(long)BFSvl{
NSNumber *ValueBFSvl = [NSNumber numberWithLong:BFSvl];
NSString *Strlbl = [NSString stringWithUTF8String: lbl]; // your old code had a memory leak here. you need to either create an autorelease object, or release it after adding to `foo`
[foo setValue:ValueBFSvl forKey:Strlbl];
}
My Recommendation is to do the following:
- (void) SetBFSV:(NSString*)key ToVal:(long)val{
NSNumber *value = [NSNumber numberWithLong:val];
[foo setValue:value forKey:key];
}
And call it like the following (from your example):
SomeValues *myBFSV = [SomeValues sharedInstance];
NSString *Bar = [NSString stringWithString:#"Label1"];// this may not be necessary...
NSLog(#"The string %#", Bar);
[myBFSV SetBFSV:Bar ToVal:25]; // don't pass a decimal for a (long)

hash a password string using SHA512 like C#

I am developing logon function for my iPhone Application, so I want to hash the password using the SHA512 hashing algorithm then get the result as NSString (the result should be the same with SHA512 in C#). After spending a lot of time in the internet, I still not find out the solution yet! :(
Is there anyone has the solution and sample code, please help me!
Thanks a lot!
[Update]
In my C# code, the password is stored using SecureString, so maybe it's cause make different byte array between objective-c and C#
This function will hash a string using SHA512. The resulting string is a hex representation of the hash:
+ (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];
}
Don't forget to include the correct header:
#include <CommonCrypto/CommonDigest.h>
I am using this one.
It matches PHP SHA512 algorithm output:
<?php `hash('sha512', 'The quick brown fox jumped over the lazy dog.');` ?>
Objective-C code:
+(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;
}

Would NSMutableArray -removeObject: also remove a NSString if it has a different memory adress?

Example: I add some NSString objects to an NSMutableArray: #"Foo", #"Bar", #“FooBar". Now somewhere else I access that array again, and I want to delete #"Foo". So I create a new NSString #"Foo", and pass it to -removeObject:. The documentation does not state on what criteria -removeObject works. I think that it looks only for the memory address, So in this case it would do nothing. Is that correct?
according to the doc for removeObject: "matches are determined on the basis of an object’s response to the isEqual: message" and strings are compared with hashes ("If two objects are equal, they must have the same hash value") so, YES, that should be incorrect.
Your example is an unfortunate one - if you use the string literal #"Foo" in two places in the code, the compiler will give them the same address (i.e. it uses the same static instance of the string). Example:
heimdall:Documents leeg$ cat foostrings.m
#import <Foundation/Foundation.h>
int main(int argc, char **argv)
{
NSString *string1 = #"Foo";
NSString *string2 = #"Foo";
printf("string1: %p\nstring2: %p\n", string1, string2);
return 0;
}
heimdall:Documents leeg$ ./foostrings
string1: 0x100001048
string2: 0x100001048