1

md5を使用して文字列(16進数)をハッシュしようとしています。ただし、出力文字列は、pythonまたはjavascript(node.js)で作成した同様の出力と一致しません。

入力文字列:

NSString *input = @"001856413a840871624d6c6f553885b5b16fae345c6bdd44afb26141483bff629df47dbd9ad0";


- (NSString *)md5:(NSString *)input {
// b2b22e766b849b8eb41b22ae85dc49b1
unsigned char md5Buffer[CC_MD5_DIGEST_LENGTH];
const char *cStr = [input UTF8String];
CC_MD5_CTX ctx;
CC_MD5_Init(&ctx);
CC_MD5_Update(&ctx, cStr, [input length]);
CC_MD5_Final(md5Buffer, &ctx);

NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
    [output appendFormat:@"%02x",md5Buffer[i]];

return output;

}

Pythonでは:

binaryCredentialString = binascii.unhexlify(input)
# Now MD5 hash the binary string    
m = hashlib.md5()
m.update(binaryCredentialString)
# Hex encode the hash to obtain the final credential string
credential = m.hexdigest()

Pythonは正しいmd5出力を返しますが、object-Cは返しません。どうしてこれなの?

どんな助けでも本当にありがたいです-パスカル

4

2 に答える 2

3

Python では 16 進数を 2 進数にデコードしていますが、Objective-C ではそうではありません。NSMutableData文字列をインスタンスにデコードし、[data bytes](および[data length]) をダイジェスト関数に提供します。

于 2013-03-10T01:20:50.563 に答える
3

これは基本的にdreamlaxの答えと同じですが、あなたは彼の答えを理解していないようです. うまくいけば、私は助けることができます(しかし、もしそうなら、あなたは彼の答えを受け入れる必要があります).

問題は、@"001856413a840871624d6c6f553885b5b16fae345c6bdd44afb26141483bff629df47dbd9ad0"文字列がエンコードする 38 バイトのバイナリ データではなく、76 文字の文字列の MD5 を実行していることです。

Python では、md5関数に入力するものは次のとおりです。

binaryCredentialString = binascii.unhexlify(input)

しかし、ObjC では次のようになります。

const char *cStr = [input UTF8String];

したがって、相当するものが必要ですunhexlify

これは、カテゴリを介してメソッド-(NSString *)hexlifyを追加しNSDataたり、カテゴリに追加したりすることで処理します。次に、Python と同じくらい読みやすい次のコードを記述します。-(NSData *)unhexlifyNSString

- (NSString *)md5:(NSString *)input {
    NSData *binaryCredentialString = [input unhexlify];
    NSMutableData *result = [NSMutableData dataWithLength:CC_MD5_DIGEST_LENGTH];
    CC_MD5([binaryCredentialString bytes],
           [binaryCredentialString length],
           [m mutableBytes]);
    return [result hexlify];
}

では、これらのカテゴリをどのように書きますか? コードを使用すると、次のようになります(テストされておらず、検証とエラー処理が必要ですが、アイデアを得る必要があります):

@implementation NSData(hexlify)
- (NSString *)hexlify {
    unsigned char *buf = [self bytes];
    size_t len = [self length];
    NSMutableString *output = [NSMutableString stringWithCapacity:len * 2];
    for(int i = 0; i < len; i++)
        [output appendFormat:@"%02x",buf[i]];
    return [NSData dataWithData:output];
}
@end

static unsigned char unhexchar(char c) {
    if (c <= '9') return c - '0';
    if (c <= 'F') return c - 'A' + 10;
    return c - 'a' + 10;
}

@implementation NSString(hexlify)
- (NSData *)unhexlify {
    const char *cStr = [self UTF8String];
    size_t len = [self length];
    NSMutableData *output = [NSMutableData dataWithLength:len / 2];
    unsigned char *buf = [output mutableBytes];
    for(int i = 0; i < len / 2; i++)
        buf[i] = unhexchar(cStr[i*2]) * 16 + unhexchar(cStr[i*2+1]);
    return [NSString stringWithString:output];
}
@end

しかし、少し検索すれば、これら 2 つのメソッドを自分で作成する代わりに、クリーンでテスト済みで最適化された実装を見つけることができると確信しています。たとえば、この質問この質問、およびSOのさまざまな他の質問を参照してください。

于 2013-03-10T02:56:34.823 に答える