On 08/04/2009, at 4:18 AM, Christopher Kane wrote:

Now that everybody else has had their say, I'll throw in my two bits: ;-)

* as others have pointed out, never store the hash of an object or data computed from the hash, nor transmit the hash of an object outside a process, if your goal is to compare it in any way with anything else (for example, storing it as [part of] keys in a database with the later hope of using the hash to retrieve records).


Right, I think this is what was probably hurting me. I've reimplemented my digest hashing to essentially follow Michael's recursive scheme.

* Using a string representation of a date is the absolute worst possibility, since it's affected by all those things listed above (time zones, locales, and calendars), plus involves components, plus is a different representation. There might be some people who would say "an all-numeric components representation would be fine [if you made sure to generate it with respect to some specific fixed calendar and time zone]", but beyond what I've already noted, with a string representation you have the excitement of different Unicode code points that could be used to represent the digits (e.g., try running in an Arabic locale) or even different number representation systems (e.g., the Roman numerals of the Romans or the base-60 of the Babylonians -- I don't know if any locales have such a thing today, but unless _you_ know, it's best to just stay away). So you should be sure to also generate the string description entirely yourself as well; don't use the system code for that.

OK, I'm avoiding string representations of the date - now you point it out that does seem fraught with difficulties.

So all that is why I suggest skipping all the extra work and intermediate steps and just use the timeIntervalSinceReferenceDate. It's a nice double, and you can compare with <, >, etc. (Of course, if you choose to hash the 8 bytes of the double as a chunk of bytes, then you have to take machine representation of doubles into account and make sure you know what you're doing there.)

I'm doing this, which is the first step in building an NSData representation of the various objects, prior to SHA-1 digesting the result. Be good to know if this is adequate for system/architecture independence. The intention is that the digest only ever sees a little- endian representation of the time interval.

@implementation NSDate (GCHash)

- (NSData*)             gc_hash
{
NSSwappedDouble nt = NSSwapHostDoubleToLittle([self timeIntervalSinceReferenceDate]);
        return [NSData dataWithBytes:&nt length:sizeof(NSSwappedDouble)];
}

@end


thanks,

Graham


_______________________________________________

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