Objective c 如何在Cocoa中创建字符串的MD5哈希?
我知道SHA-1是首选,但这个项目需要我使用MD5Objective c 如何在Cocoa中创建字符串的MD5哈希?,objective-c,cocoa,hash,md5,Objective C,Cocoa,Hash,Md5,我知道SHA-1是首选,但这个项目需要我使用MD5 #include <openssl/md5.h> - (NSString*) MD5Hasher: (NSString*) query { NSData* hashed = [query dataUsingEncoding:NSUTF8StringEncoding]; unsigned char *digest = MD5([hashed bytes], [hashed length], NULL); NS
#include <openssl/md5.h>
- (NSString*) MD5Hasher: (NSString*) query {
NSData* hashed = [query dataUsingEncoding:NSUTF8StringEncoding];
unsigned char *digest = MD5([hashed bytes], [hashed length], NULL);
NSString *final = [NSString stringWithUTF8String: (char *)digest];
return final;
}
我搞不懂它的意思。我认为摘要是指向原始二进制哈希的指针。在下一行中,您试图将其解释为UTF-8字符串,但它很可能不包含合法的UTF-8编码字符序列
我希望您希望使用任何您认为合适的算法将16字节无符号字符静态数组转换为32个ASCII十六进制字符[0-9a-f] 这是我使用的类别: NSString+MD5.h
@interface NSString (MD5)
- (NSString *)MD5String;
@end
@interface NSString (MD5)
- (NSString *)MD5;
@end
NSString+MD5.m
#import <CommonCrypto/CommonDigest.h>
@implementation NSString (MD5)
- (NSString *)MD5String {
const char *cStr = [self UTF8String];
unsigned char result[CC_MD5_DIGEST_LENGTH];
CC_MD5( cStr, (CC_LONG)strlen(cStr), result );
return [NSString stringWithFormat:
@"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
result[0], result[1], result[2], result[3],
result[4], result[5], result[6], result[7],
result[8], result[9], result[10], result[11],
result[12], result[13], result[14], result[15]
];
}
@end
#import "NSString+MD5.h"
#import <CommonCrypto/CommonDigest.h>
@implementation NSString (MD5)
- (NSString *)MD5 {
const char * pointer = self.UTF8String;
unsigned char md5Buffer[CC_MD5_DIGEST_LENGTH];
CC_MD5(pointer, (CC_LONG)strlen(pointer), md5Buffer);
NSMutableString * string = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
[string appendFormat:@"%02x", md5Buffer[i]];
}
return string;
}
@end
MD5函数不返回C字符串,它返回指向某些字节的指针。你不能把它当作一根绳子 如果要创建字符串,则需要使用这些字节的十六进制值构建字符串。以下是一种将其作为NSData上的类别执行的方法:
#import <CommonCrypto/CommonDigest.h>
@implementation NSData (MMAdditions)
- (NSString*)md5String
{
unsigned char md5[CC_MD5_DIGEST_LENGTH];
CC_MD5([self bytes], [self length], md5);
return [NSString stringWithFormat: @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
md5[0], md5[1],
md5[2], md5[3],
md5[4], md5[5],
md5[6], md5[7],
md5[8], md5[9],
md5[10], md5[11],
md5[12], md5[13],
md5[14], md5[15]
];
}
@end
#导入
@实施NSData(MMAdditions)
-(NSString*)md5String
{
无符号字符md5[CC_md5_DIGEST_LENGTH];
CC_MD5([self bytes],[self length],MD5);
返回[NSString stringWithFormat:@“%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x”,
md5[0],md5[1],
md5[2],md5[3],
md5[4],md5[5],
md5[6],md5[7],
md5[8],md5[9],
md5[10],md5[11],
md5[12],md5[13],
md5[14],md5[15]
];
}
@结束
cdespinosa和irsk已经向您展示了您的实际问题,所以让我来看看您的GDB成绩单:
您已将摘要
打印为C字符串。您可以在这里看到,这个字符串是原始字节;因此,所有的八进制转义符(例如,\020
,\225
)和一对标点符号(/
和^
)。它不是您期望的可打印ASCII十六进制表示形式。幸运的是,其中没有零字节;否则,您就不会打印整个哈希
final
为nil
。这是有道理的,因为上面的字符串不是有效的UTF-8;同样,它只是原始数据字节<代码>字符串WithUTF8String:需要UTF-8编码的文本字符串;您没有给它一个,因此它返回了nil
为了传递原始数据,您可以使用NSData。在本例中,我认为您需要十六进制表示,因此您需要按照irsk显示的方式自己创建十六进制表示
最后,考虑到你的输入没有被有效的UTF-8字符串限制,你是多么幸运。如果有,你就不会注意到这个问题。您可能希望使用此输入为此哈希方法构造一个单元测试
您的程序在objc\u msgSend
中崩溃(具体问题:“访问错误”、“地址无效”)。这是因为digest
要么根本不是Cocoa/CF对象,要么是一个但被释放的对象。在这种情况下,这是因为摘要不是Cocoa对象;它是一个字节的C数组,如上面的p摘要
行所示
记住,Objective-C是C的超集。所有的C都不改变地存在于其中。这意味着有C数组(例如,char[]
)和Cocoa的NSarray并排出现。此外,由于NSArray来自Cocoa框架,而不是Objective-C语言,因此无法使NSArray对象与C数组互换:不能在Cocoa数组上使用下标运算符,也不能向C数组发送Objective-C消息。@implementation NSString(MD5)
@implementation NSString (MD5)
+ (NSString *)formattedMD5:(const char *)data length:(unsigned long)len
{
unsigned char *digest = MD5((unsigned const char *)data, len, NULL);
NSMutableArray *values = [[NSMutableArray alloc] init];
for (int i = 0; i < strlen((char *)digest); i++)
{
char hexValue[4];
sprintf(hexValue, "%02X", digest[i]);
[values addObject:[NSString stringWithCString:hexValue length:strlen(hexValue)]];
}
// returns a formatted MD5 fingerprint like
// 00:00:00:00:00:00:00:00:00
return [values componentsJoinedByString:@":"];
}
@end
+(NSString*)格式化MD5:(const char*)数据长度:(无符号长)len
{
无符号字符*摘要=MD5((无符号常量字符*)数据,len,NULL);
NSMUTABLEARRY*值=[[NSMUTABLEARRY alloc]init];
对于(inti=0;i
Facebook使用此
#import <CommonCrypto/CommonDigest.h>
#导入
+(NSString*)md5HexDigest:(NSString*)输入{
const char*str=[输入UTF8String];
无符号字符结果[CC_MD5_DIGEST_LENGTH];
CC_MD5(str,strlen(str),结果);
NSMutableString*ret=[NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH*2];
对于(int i=0;i我使用了这种方法:
NSString+MD5.h
@interface NSString (MD5)
- (NSString *)MD5String;
@end
@interface NSString (MD5)
- (NSString *)MD5;
@end
NSString+MD5.m
#import <CommonCrypto/CommonDigest.h>
@implementation NSString (MD5)
- (NSString *)MD5String {
const char *cStr = [self UTF8String];
unsigned char result[CC_MD5_DIGEST_LENGTH];
CC_MD5( cStr, (CC_LONG)strlen(cStr), result );
return [NSString stringWithFormat:
@"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
result[0], result[1], result[2], result[3],
result[4], result[5], result[6], result[7],
result[8], result[9], result[10], result[11],
result[12], result[13], result[14], result[15]
];
}
@end
#import "NSString+MD5.h"
#import <CommonCrypto/CommonDigest.h>
@implementation NSString (MD5)
- (NSString *)MD5 {
const char * pointer = self.UTF8String;
unsigned char md5Buffer[CC_MD5_DIGEST_LENGTH];
CC_MD5(pointer, (CC_LONG)strlen(pointer), md5Buffer);
NSMutableString * string = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
[string appendFormat:@"%02x", md5Buffer[i]];
}
return string;
}
@end
这些答案是正确的,但令人困惑。我发布了一个工作示例,因为我对大多数其他答案都有疑问。该代码经过测试,适用于Mac OS X 10.12.X和iOS 10.1.X
你的班级
#import <CommonCrypto/CommonDigest.h>
@interface YourClass : NSObject
+ (NSString *) md5:(NSString *) input;
@end
另一类
-(void) Test
{
//call by [self Test] or use somewhere in your code.
NSString *password = @"mypassword123";
NSString *md5 = [YourClass md5:password];
NSLog(@"%@", password);
NSLog(@"%@", md5);
}
我导入了NSString+MD5。但是Xcode和编译器说:“找不到NSString的可见接口”可能使用常量CC_MD5_DIGEST_LENGTH并强制转换为CC_LONG以实现64位兼容性const char*cStr=[self UTF8String];无符号字符结果[CC_MD5_DIGEST_LENGTH];CC_MD5(cStr,(CC_LONG)strlen(cStr),result)
-(NSString*)MD5String{const char*cStr=[self UTF8String];无符号字符结果[CC_MD5_DIGEST_LENGTH];CC_MD5(cStr,(int)strlen(cStr),result);//这是MD5调用返回[NSString stringWithFormat:@”%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x]、结果[3]、结果[4]、结果[5]、结果[6]、结果[7]、结果[8]、结果[9]、结果[10]、结果[11]、结果[12]、结果[13]、结果[14]、结果[15];如果您不知道常量CC_MD5_DIGEST_长度来自何处,可以通过导入文件+1中的CommonCrypto/CommonDigest.h来查找(CC_LONG)
针对strlen(指针)
解决Xcode中的隐式转换和静音警告。如何调用此方法?
#import "NSString+MD5.h"
#import <CommonCrypto/CommonDigest.h>
@implementation NSString (MD5)
- (NSString *)MD5 {
const char * pointer = self.UTF8String;
unsigned char md5Buffer[CC_MD5_DIGEST_LENGTH];
CC_MD5(pointer, (CC_LONG)strlen(pointer), md5Buffer);
NSMutableString * string = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
[string appendFormat:@"%02x", md5Buffer[i]];
}
return string;
}
@end
NSString * myString = @"test";
NSString * md5 = [myString MD5];
- (NSString*)MD5:(NSData *) data
{
// Create byte array of unsigned chars
unsigned char md5Buffer[CC_MD5_DIGEST_LENGTH];
// Create 16 byte MD5 hash value, store in buffer
CC_MD5([data bytes], (CC_LONG)data.length, md5Buffer);
// Convert unsigned char 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;
}
NSString *yourStrToBeConverted;
NSData* data = [yourStrToBeConverted dataUsingEncoding:NSUTF8StringEncoding];
NSString *md5res=[self MD5:data];
#import <CommonCrypto/CommonDigest.h>
@interface YourClass : NSObject
+ (NSString *) md5:(NSString *) input;
@end
#import YourClass.h
+ (NSString *) md5:(NSString *) input
{
const char *cStr = [input UTF8String];
unsigned char digest[CC_MD5_DIGEST_LENGTH];
CC_MD5(cStr, (uint32_t)strlen(cStr), digest);
NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
[output appendFormat:@"%02x", digest[i]]; //%02X for capital letters
return output;
}
#import "YourClass.h"
-(void) Test
{
//call by [self Test] or use somewhere in your code.
NSString *password = @"mypassword123";
NSString *md5 = [YourClass md5:password];
NSLog(@"%@", password);
NSLog(@"%@", md5);
}