6

次の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 と言うと奇妙な文字が表示されます。私が本当に欲しいのは16進文字列ですが、それを取得する方法がわかりません。これは iPhone 3.0 SDK を使用しています。

現時点では、渡した文字列はすべてNULLに戻ります。

4

4 に答える 4

28

私のバージョンの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;
}

そして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;
}
于 2009-09-29T14:31:49.717 に答える
3

簡単な答え: gcc 警告をオンにします (-Wall)。

長い答え:

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

壊れています: NSData 引数が必要な場所で C 文字列を使用しようとしています。使用する

NSMutableData *dataToHash = [str dataUsingEncoding:NSUTF8StringEncoding];

代わりは。

メソッドの残りの部分は SHA1 バッファを取得し、このデータを UTF-8 C 文字列として解釈しようとします。これにより、クラッシュしたり、予期しない結果が生じる可能性があります。まず、バッファは UTF-8 文字列ではありません。次に、null で終了していません。

必要なのは、SHA1 を base 64 または同様の文字列に変換することです。これを行う方法についての素敵な投稿があります。

于 2009-08-30T13:01:58.050 に答える
1

これが私が最終的に得たものです。次のステップは、ヘルパー クラスの静的メソッドではなく、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;
}
于 2009-08-31T12:47:25.253 に答える