Code: https://github.com/D-Programming-Language/phobos/pull/646 Docs: http://dl.dropbox.com/u/24218791/d/phobos/std_hash_hash.html http://dl.dropbox.com/u/24218791/d/phobos/std_hash_crc.html http://dl.dropbox.com/u/24218791/d/phobos/std_hash_md.html http://dl.dropbox.com/u/24218791/d/phobos/std_hash_sha.html
I just had another look at my initial std.hash design, and I realized that the API could be simplified a little: There's a reset function that's implemented in every hash. For sha1, md5, crc32 it only forwards to the start function though. So I'm not sure how useful this function is or if it should be dropped. Advantages of keeping it: * 'reset' better documents what's done than 'start' if the hash has already processed data * Are there hashes which can implement a reset function in a faster way than calling start again? Cons: * Adds an additional function which probably isn't necessary The start function is probably not needed as well. Tango doesn't have a start function or something similar, but it could use constructors for this (I only looked at docs, not code). We can't use constructors, so a start function would be necessary for advanced initialization. But do we actually need that advanced initialization? SHA1, MD5 and CRC32 just do a "this = typeof(this).init" so a start function isn't necessary here. Advantages of keeping it: * Are there hash algorithms which need some sort of complex initialization which can't be done with .init / default values? * If we drop both start and reset the only way to reset the internal state is calling finish. This might be a little less efficient than a start/reset method. Advantages of dropping it: * Using hashes is easier, no need to call 'start' before hashing data I think someone more familiar with hash functions than me needs to answer the "do we need start/reset functions" questions. API question: CRC32 sums are usually presented as a uint, not a ubyte[4]. To fit the rest of the API ubyte[4] is used. Now there's a small annoying detail: The CRC32 should be printed in LSB-first order. When printing an uint like this, that works well: writefln("%#x", 4157704578); //0xf7d18982 but this doesn't: toHexString(*cast(ubyte[4]*)&4157704578); //8289D1F7 I can't change toHexString as it's used for all hashes and it's correct for SHA1, MD5, ... So I currently use bswap in the CRC32 finish() implementation to fix this issue. Now the question is should I provide an additional finishUint function which avoids the bswap? Implementation issue: The current implementation of SHA1 and MD5 uses memcpy which doesn't work in CTFE IIRC and which also prevents the code from being pure. I could replace those memcpy calls with array copying but I'm not sure if memcpy was used for performance, so I'd like to keep it as long as we have no performance tests.