2009-08-30 7 views
5

を返しています:はSHA1機能をNSStringの書き込もうとしたが、それは私が次の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に戻ってきます。

+0

別名:クラスメソッドではなくNSStringのカテゴリとして実装するのが良いです。メソッドは - (NSString *)sha1Stringになります。それをクラスメソッドにしておきたい場合は、+(NSString *)sha1StringForString:(NSString *)文字列のような名前が必要です。 "sha1"(バイナリ表現)とsha1Stringの間の混乱は、まさにあなたが最初に問題を抱えていた理由です。適切な命名は、後で同じタイプの混乱を防ぐのに役立ちます。 –

答えて

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をベース64などの文字列に変換します。それを行う方法についてHere's a nice post

+0

ありがとう、私はこのCビジネスの大部分を新しくしましたが、それに従うのはかなり簡単です – rustyshelf

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

これは、純粋なASCII文字列のハッシュだけを作成することができます。 –

+0

チップをありがとうが、それは私が必要なすべてです。 – rustyshelf

26

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

lowercaseStringを呼び出す必要はありません。 '02X'を '02x'に変更するだけです。 – Seunghoon

+0

完璧!たくさんのことがあります – virata

-1

グリコール、 必要になりますあなたのCC_SHA1_DIGEST_LENGTH定数を定義する必要があります。それはNISTの仕様に従ったSHA-1ダイジェストの長さで、たぶん20に設定する必要があります。http://www.itl.nist.gov/fipspubs/fip180-1.htm

+1

これは ''で定義されています –

関連する問題