我有以下的Objective-C的功能:
+(NSString *)stringToSha1:(NSString *)str{
NSMutableData *dataToHash = [[NSMutableData alloc] init];
[dataToHash appendData:[str dataUsingEncoding:NSUTF8StringEncoding]];
unsigned char hashBytes[CC_SHA1_DIGEST_LENGTH];
CC_SHA1([dataToHash bytes], [dataToHash length], hashBytes);
NSData *encodedData = [NSData dataWithBytes:hashBytes length:CC_SHA1_DIGEST_LENGTH];
[dataToHash release];
NSString *encodedStr = [NSString stringWithUTF8String:[encodedData bytes]];
//NSString *encodedStr = [[NSString alloc] initWithBytes:[encodedData bytes]
// length:[encodedData length] encoding: NSUTF8StringEncoding];
NSLog(@"String is %@", encodedStr);
return encodedStr;
}
我正在试图做的是采取一个NSString和SHA1编码。 这部分似乎是工作,我想我在哪里跌倒在如何将NSData对象转换回清晰的字符串。 如果我使用UTF8编码,我得到的空白,如果我说我ASCII得到奇怪的字符。 我真正想要的是十六进制字符串,但我不知道如何得到它。 这是使用iPhone 3.0 SDK。
目前,我通过在所有的字符串回来了NULL。
答案很简单:打开gcc的警告(-Wall)。
长一点的回答:
NSMutableData *dataToHash = [[NSMutableData alloc] init];
[dataToHash appendData:[str dataUsingEncoding:NSUTF8StringEncoding]];
坏:您尝试使用C字符串,其中一个NSData参数的预期。 使用
NSMutableData *dataToHash = [str dataUsingEncoding:NSUTF8StringEncoding];
代替。
该方法的其余部分取SHA1缓冲器和试图解释该数据作为UTF-8 C字符串,这可能会崩溃或给出任何意外的结果。 首先,缓冲器不是UTF-8字符串。 其次,它不是空终止。
你需要的是对SHA1变换成基64或类似的字符串。 这里是一个不错的职位如何做到这一点。
我SHA1功能的版本(simplier):
- (NSString *)sha1:(NSString *)str {
const char *cStr = [str UTF8String];
unsigned char result[CC_SHA1_DIGEST_LENGTH];
CC_SHA1(cStr, strlen(cStr), result);
NSString *s = [NSString stringWithFormat:
@"%02x%02x%02x%02x%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],
result[16], result[17], result[18], result[19]
];
return s;
}
和MD5:
- (NSString *)md5:(NSString *)str {
const char *cStr = [str UTF8String];
unsigned char result[CC_MD5_DIGEST_LENGTH];
CC_MD5(cStr, strlen(cStr), result);
NSString *s = [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]
];
return s;
}
这是我结束了,下一步将是将其转换为NSString的,而不是在一个辅助类的静态方法的分类:
+(NSString *)stringToSha1:(NSString *)str{
const char *s = [str cStringUsingEncoding:NSASCIIStringEncoding];
NSData *keyData = [NSData dataWithBytes:s length:strlen(s)];
// This is the destination
uint8_t digest[CC_SHA1_DIGEST_LENGTH] = {0};
// This one function does an unkeyed SHA1 hash of your hash data
CC_SHA1(keyData.bytes, keyData.length, digest);
// Now convert to NSData structure to make it usable again
NSData *out = [NSData dataWithBytes:digest length:CC_SHA1_DIGEST_LENGTH];
// description converts to hex but puts <> around it and spaces every 4 bytes
NSString *hash = [out description];
hash = [hash stringByReplacingOccurrencesOfString:@" " withString:@""];
hash = [hash stringByReplacingOccurrencesOfString:@"<" withString:@""];
hash = [hash stringByReplacingOccurrencesOfString:@">" withString:@""];
NSLog(@"Hash is %@ for string %@", hash, str);
return hash;
}
二,你需要定义你的CC_SHA1_DIGEST_LENGTH不变,大概到20,因为这是根据在NIST规范中的SHA-1的长度消化http://www.itl.nist.gov/fipspubs/fip180-1.htm