代码之家  ›  专栏  ›  技术社区  ›  rustyshelf

尝试编写NSString sha1函数,但返回null

  •  6
  • rustyshelf  · 技术社区  · 17 年前

    我有以下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。

    4 回复  |  直到 17 年前
        1
  •  28
  •   ItalyPaleAle    14 年前

    我的SHA1函数版本(更简单):

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

    - (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;
    }
    
        2
  •  3
  •   Nikolai Ruhe    17 年前

    简短的回答:打开gcc警告(-Wall)。

    长答案:

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

    已损坏:您尝试在需要NSData参数的地方使用C字符串。使用

    NSMutableData *dataToHash = [str dataUsingEncoding:NSUTF8StringEncoding];
    

    Here's a nice post 关于如何做到这一点。

        3
  •  1
  •   rustyshelf    17 年前

    这就是我最终得到的结果,下一步是将其转换为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;
    }