Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 如何在Cocoa中创建字符串的MD5哈希?_Objective C_Cocoa_Hash_Md5 - Fatal编程技术网

Objective c 如何在Cocoa中创建字符串的MD5哈希?

Objective 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

我知道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);
    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);
}