On Sun, Apr 5, 2009 at 7:23 PM, Graham Cox <graham....@bigpond.com> wrote:
> This leaves me with a problem - how to generate a SHA-1 hash of an arbitrary
> dictionary that is likely to remain stable under different architectures, OS
> versions, and so on.

Of an *arbitrary* dictionary? Can't be done. Class Foo might not have
a stable hash, even in theory (like if it wraps a file handle), and if
one is in your dictionary then you're hosed.

But you probably are just dealing with property list types, or perhaps
a few others. You know ahead of time what types you'll have, so you
can just implement the hash recursively, like so:

@implementation NSDictionary (SHA1Hashing)
- (NSData *)gc_sha1hash {
    NSMutableData *subhashes = [NSMutableData data];
    for(id key in [[self allKeys]
sortedArrayUsingSelector:@selector(compare:)]) {
        [subhashes appendData:[key gc_sha1hash]];
        [subhashes appendData:[[self objectForKey:key] gc_sha1hash]];
    }
    return [subhashes gc_sha1hash];
}
@end

Then define -gc_sha1hash for all the other classes you expect to
encounter as well. (The prefix is just to ensure that you don't
overwrite a hypothetical Apple implementation of a -sha1hash method.)

Implementing it for NSData is easy, you've done that. For classes like
NSString or NSDate, figure out a canonical way to convert them to an
NSData. For NSString, you can use one of the "WithCanonicalMapping"
methods, then convert to UTF-8. For NSDate, that whole class is
basically just a wrapper around a single value, the return value of
-timeIntervalSinceReferenceDate, so you could just print that into a
string and then hash the string. For NSArray, follow an approach
similar to NSDictionary. The key is to reduce everything down to an
NSData or something else you've already defined a hash for, like an
NSString, and do perform that reduction in a way which you control and
which is reproducible. (That last part is why I sort the keys in the
code above, since NSDictionary can give them in an arbitrary order
which won't be consistent across runs.)

Mike
_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to