2009-08-30 16 views
5

tôi có chức năng Objective-C sau:Đang cố gắng để Viết NSString chức năng sha1, nhưng nó trở vô

+(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; 

} 

Những gì tôi đang cố gắng làm là lấy một NSString và SHA1 mã hóa nó. Phần đó dường như đang làm việc, tôi nghĩ rằng nơi tôi đang rơi xuống là làm thế nào để chuyển đổi các đối tượng NSData trở lại một chuỗi dễ đọc. Nếu tôi sử dụng mã hóa UTF8, tôi sẽ bị trống, nếu tôi nói ASCII, tôi có các ký tự lạ. Những gì tôi thực sự muốn là chuỗi hex, nhưng tôi không có ý tưởng làm thế nào để có được nó. Điều này đang sử dụng iPhone 3.0 SDK.

Hiện tại bất kỳ chuỗi ký tự nào mà tôi vượt qua đều trả về NULL.

+0

Vấn đề riêng biệt: điều này được triển khai tốt hơn dưới dạng danh mục trên NSString thay vì phương pháp lớp học. Phương thức sẽ là - (NSString *) sha1String. Nếu bạn tìm thấy bạn muốn giữ cho nó một phương thức lớp, nó sẽ có một tên như + (NSString *) sha1StringForString: (NSString *) chuỗi. Sự nhầm lẫn giữa một "sha1" (mà là một đại diện nhị phân), và một sha1String là chính xác lý do tại sao bạn gặp rắc rối ở nơi đầu tiên. Việc đặt tên thích hợp sẽ giúp ngăn ngừa sự nhầm lẫn sau này cùng loại. –

Trả lời

3

Trả lời ngắn: bật cảnh báo gcc (-Wall).

Long trả lời:

NSMutableData *dataToHash = [[NSMutableData alloc] init]; 
[dataToHash appendData:[str dataUsingEncoding:NSUTF8StringEncoding]]; 

được chia: Bạn cố gắng sử dụng một chuỗi C, nơi một cuộc tranh cãi NSData được mong đợi. Sử dụng

NSMutableData *dataToHash = [str dataUsingEncoding:NSUTF8StringEncoding]; 

thay thế.

Phần còn lại của phương thức có bộ đệm SHA1 và cố gắng diễn giải dữ liệu này dưới dạng chuỗi UTF-8 C, có thể bị lỗi hoặc đưa ra bất kỳ kết quả không mong muốn nào. Đầu tiên, bộ đệm không phải là một chuỗi UTF-8. Thứ hai, nó không phải là null chấm dứt.

Điều bạn muốn là chuyển đổi SHA1 thành cơ số 64 hoặc chuỗi tương tự. Here's a nice post về cách thực hiện điều đó.

+0

cảm ơn, tôi là người mới đối với hầu hết doanh nghiệp C này, nhưng có vẻ khá dễ theo dõi – rustyshelf

1

Đây là những gì tôi đã kết thúc với, bước tiếp theo sẽ là để chuyển đổi nó trở thành một loại của NSString thay vì một phương pháp tĩnh trong một lớp helper:

+(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; 
} 
+1

Điều này chỉ có thể tạo các băm cho các chuỗi ASCII thuần túy. –

+0

Cảm ơn lời khuyên, nhưng đó là tất cả những gì tôi cần. – rustyshelf

26

phiên bản của tôi về chức năng SHA1 (đơn giản hơn):

- (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; 
} 

Và 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; 
} 
+3

Bạn không cần phải gọi lowercaseString. Chỉ cần thay đổi '02X' thành '02x'. – Seunghoon

+0

hoàn hảo! thanx rất nhiều – virata

-1

glycol, Bạn sẽ cần xác định hằng số CC_SHA1_DIGEST_LENGTH của bạn, có thể là 20, vì đó là độ dài của thông báo SHA-1 theo thông số NIST tại http://www.itl.nist.gov/fipspubs/fip180-1.htm

+1

Được định nghĩa trong '' –