August 15, 2012
On Wednesday, 15 August 2012 at 08:13:27 UTC, Dmitry Olshansky wrote:
> AFAIK it'a method of HashAlgorithm Object.

It's a minor design detail, see the example: the method is called on each file without any explicit preparations and without calls to methods like TransformBlock. That's how stateless computation usually looks - it's just done and that's all.
August 15, 2012
On Wednesday, 15 August 2012 at 08:17:14 UTC, Kagamin wrote:
> On Wednesday, 15 August 2012 at 08:13:27 UTC, Dmitry Olshansky wrote:
>> AFAIK it'a method of HashAlgorithm Object.
>
> It's a minor design detail, see the example […]

No, it's not a »minor design detail«, at least not regarding what has been the topic of the discussion here – you can always provide a simple wrapper function in the proposed design and call it »stateless« as well (in fact, an implementation has already been posted, IIRC).

The point is that the ability to execute a hashing operation block by block is necessary, and that this operation is not analogous to reduce() because it potentially needs internal state.

David
August 15, 2012
On Wednesday, 15 August 2012 at 08:17:01 UTC, David Nadlinger wrote:
> On Wednesday, 15 August 2012 at 07:41:20 UTC, Kagamin wrote:
>> On Thursday, 9 August 2012 at 09:59:48 UTC, David Nadlinger wrote:
>>> Hash functions are _not_ analogous to reduce(), because the operation performed by reduce() is stateless, whereas hash functions generally have some internal state.
>>
>> An example of stateless hash in .net:
>> http://msdn.microsoft.com/en-us/library/xa627k19.aspx
>
> http://msdn.microsoft.com/en-us/library/system.security.cryptography.hashalgorithm.state
>
> David

Ok, but HashAlgorithm still supports stateless interface which consists of a single method with a couple of overloads, the example in the ComputeHash article speaks for itself.
August 15, 2012
On 15-Aug-12 12:17, Kagamin wrote:
> On Wednesday, 15 August 2012 at 08:13:27 UTC, Dmitry Olshansky wrote:
>> AFAIK it'a method of HashAlgorithm Object.
>
> It's a minor design detail, see the example: the method is called on
> each file without any explicit preparations and without calls to methods
> like TransformBlock. That's how stateless computation usually looks -
> it's just done and that's all.

Brrr. It's how convenience wrapper works :)

And I totally expect this to call the same code and keep the same state during the work.

E.g. see std.digest.digest functions digest or hexDigest you could call it stateless in the same vane.
August 15, 2012
On Wednesday, 15 August 2012 at 08:25:51 UTC, Dmitry Olshansky wrote:
> Brrr. It's how convenience wrapper works :)
>
> And I totally expect this to call the same code and keep the same state during the work.
>
> E.g. see std.digest.digest functions digest or hexDigest you could call it stateless in the same vane.

Well there was a wish for stateless hash, Walter even posted the required interface:
auto result = file.byChunk(4096 * 1025).joiner.hash();

I just pointed out, that possibly stateful implementation doesn't prevent stateless interface. Can one even say that the implementation is stateful given just a stateless interface?

One can even call reduce stateful because it does keep track of the result which is or a part of its state.
August 15, 2012
On Wednesday, 15 August 2012 at 08:45:35 UTC, Kagamin wrote:
> I just pointed out, that possibly stateful implementation doesn't prevent stateless interface. Can one even say that the implementation is stateful given just a stateless interface?

And our point is that such an interface is trivial to implement over a »stateful« interface, and even already exists. Maybe you want to peruse some of the old posts?

David
August 15, 2012
On Wednesday, 8 August 2012 at 16:47:35 UTC, Johannes Pfau wrote:

> std.hash.digest doesn't sound too bad. We could have std.hash.func (or
> a better named module ;-) for general hash functions later.

Three basic types of hash functions are:

1) Hash - for fast searching and indexing in data structures
2) Checksum - detects the accidental errors in files, archives, streams
3) Message digest code - prevents the intentional modification of data

They should not be mixed IMHO.

1) should go into std.container or (maybe) std.algorithm
2) std.checksum
3) std.crypto.mdc or std.crypto.digest

August 15, 2012
On Wednesday, 15 August 2012 at 08:49:26 UTC, RivenTheMage wrote:
> Three basic types of hash functions are:
>
> 1) Hash - for fast searching and indexing in data structures
> 2) Checksum - detects the accidental errors in files, archives, streams
> 3) Message digest code - prevents the intentional modification of data
>
> They should not be mixed IMHO.

Why? 1) might have a different interface than the others, but 2) and 3) only differ in their cryptological properties, the interface will likely be just the same – or what are you thinking about?

David
August 15, 2012
On Wednesday, 15 August 2012 at 08:55:30 UTC, David Nadlinger
wrote:

> Why? 1) might have a different interface than the others, but 2) and 3) only differ in their cryptological properties, the interface will likely be just the same – or what are you thinking about?
>
> David

The "only" difference between 2) and 3) is a big difference.
CRC32, Adler, etc. are NOT a cryptographic hash fuctions. Their
purpose is to detect accidental errors caused by malfunction of
hardware or software, nothing more.

For me, it's weird and confusing to mix checksums and MDCs.

It's about organizing the standard library for the better
usability. That is the whole point of modules. After all, you can
place all the standard library in one module, why not? :-)
August 15, 2012
Another example is a systematic error-correcting codes. The
"only" difference between them and checksums is the ability to
correct errors, not just detect them. CRC or MD5 can be viewed as
systematic code with zero error-correcting ability.

Should we mix Reed-Solomon codes and MD5 in one module? I don't think so.