Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Float.hash is based on the reduction of float modulo the prime #4581

Conversation

akzhan
Copy link
Contributor

@akzhan akzhan commented Jun 16, 2017

P= 2**HASH_BITS - 1.

It's designed so that x.hash == y.hash whenever x and y are numerically equal, even if x and y have different types.

Implementation same as CPython pyhash.c.

https://github.com/python/cpython/blob/master/Python/pyhash.c

Fixes #3932.

@akzhan
Copy link
Contributor Author

akzhan commented Jun 16, 2017

@asterite I should note that proposed implementation of Float64.hash returns same hash high bits for 1_i32 and 1_f64,

These values are equal in terms of ==, so now {1 => 10, 1.0 => 20}[1] will return 20.

I suppose that's good.

Hashes for different binary representations of same float number now equal too (canonicalization).

@akzhan akzhan changed the title Float64.hash is based on the reduction of float64 modulo the prime Float.hash is based on the reduction of float modulo the prime Jun 16, 2017
@akzhan akzhan force-pushed the Float64.hash-inspired-by-_Py_HashDouble branch from 8a638d5 to 2b6a792 Compare June 16, 2017 20:49
Copy link
Contributor

@bew bew left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your last "formatting" commit looks weird to me, is it the result of the Crystal tool formatter?

@akzhan
Copy link
Contributor Author

akzhan commented Jun 16, 2017

@bew yes, it is. Formatted by bin/crystal tool format.

@akzhan akzhan force-pushed the Float64.hash-inspired-by-_Py_HashDouble branch 3 times, most recently from fec9bd6 to 8de32ac Compare June 26, 2017 17:44
funny-falcon added a commit to funny-falcon/crystal that referenced this pull request Jun 27, 2017
doesn't include crystal-lang#4581 yet (number normalization)
funny-falcon added a commit to funny-falcon/crystal that referenced this pull request Jul 5, 2017
To protect against Hash DoS, change the way hash value is computed.
Class|Struct should define method `def hash(hasher)` and call
`hasher << @ivar` inside.

As an option, for speed, and for backward compatibility, `def hash`
still could be implemented. It will be used for Hash of matched type.
`Thread#hash` and `Signal#hash` is implemented as unseeded cause they are
 used before `StdHasher @@seed` is initialized.

But it is better to implement `def hash(hasher)`.

StdHasher is default hasher that uses `hash(hasher)` and it is used as default
seeded hasher. It also implements `unseeded` for `Enums`.

Also, number normalization for hashing introduced, ie rule 'equality
forces hash equality' is forced (`a == b` => `a.hash == b.hash`).
Normalization idea is borrowed from Python implementation.

Fixes crystal-lang#4578
Prerequisite for crystal-lang#4557
Replaces crystal-lang#4581
funny-falcon added a commit to funny-falcon/crystal that referenced this pull request Jul 5, 2017
To protect against Hash DoS, change the way hash value is computed.
Class|Struct should define method `def hash(hasher)` and call
`hasher << @ivar` inside.

As an option, for speed, and for backward compatibility, `def hash`
still could be implemented. It will be used for Hash of matched type.
`Thread#hash` and `Signal#hash` is implemented as unseeded cause they are
 used before `StdHasher @@seed` is initialized.

But it is better to implement `def hash(hasher)`.

StdHasher is default hasher that uses `hash(hasher)` and it is used as default
seeded hasher. It also implements `unseeded` for `Enums`.

Also, number normalization for hashing introduced, ie rule 'equality
forces hash equality' is forced (`a == b` => `a.hash == b.hash`).
Normalization idea is borrowed from Python implementation.
(idea by Akzhan Abdulin @akzhan)

Fixes crystal-lang#4578
Prerequisite for crystal-lang#4557
Replaces crystal-lang#4581
@akzhan
Copy link
Contributor Author

akzhan commented Jul 5, 2017

Should be closed due to a more accurate #4675.

@akzhan akzhan closed this Jul 5, 2017
funny-falcon added a commit to funny-falcon/crystal that referenced this pull request Jul 17, 2017
To protect against Hash DoS, change the way hash value is computed.
Class|Struct should define method `def hash(hasher)` and call
`hasher << @ivar` inside.

As an option, for speed, and for backward compatibility, `def hash`
still could be implemented. It will be used for Hash of matched type.
`Thread#hash` and `Signal#hash` is implemented as unseeded cause they are
 used before `StdHasher @@seed` is initialized.

Hash::Hasher is default hasher that uses `hash(hasher)` and it is used as default
seeded hasher.

Also, number normalization for hashing introduced, ie rule 'equality
forces hash equality' is forced (`a == b` => `a.hash == b.hash`).
Normalization idea is borrowed from Python implementation.
It fixes several issues with BigInt and BigFloat on 32bit platform,
but not all issues.

Fixes crystal-lang#4578
Fixes crystal-lang#3932
Prerequisite for crystal-lang#4557
Replaces crystal-lang#4581
Correlates with crystal-lang#4653
funny-falcon added a commit to funny-falcon/crystal that referenced this pull request Aug 24, 2017
Prepare hash infrastructor to future change of hashing algrorithm
to protect against Hash DoS.
Class|Struct should define method `def hash(hasher)` and call
`hasher << @ivar` inside.

As an option, for speed, and for backward compatibility, `def hash`
still could be implemented. It will be used for Hash of matched type.
`Thread#hash` and `Signal#hash` is implemented as unseeded cause they are
 used before `StdHasher @@seed` is initialized.

Hash::Hasher is default hasher that uses `hash(hasher)` and it is used as
default seeded hasher.

Also, number normalization for hashing introduced, ie rule 'equality
forces hash equality' is forced (`a == b` => `a.hash == b.hash`).
Normalization idea is borrowed from Python implementation.
It fixes several issues with BigInt and BigFloat on 32bit platform,
but not all issues.

Fixes crystal-lang#4578
Fixes crystal-lang#3932
Prerequisite for crystal-lang#4557
Replaces crystal-lang#4581
Correlates with crystal-lang#4653
funny-falcon added a commit to funny-falcon/crystal that referenced this pull request Aug 24, 2017
Prepare hash infrastructor to future change of hashing algrorithm
to protect against Hash DoS.
Class|Struct should define method `def hash(hasher)` and call
`hasher << @ivar` inside.

As an option, for speed, and for backward compatibility, `def hash`
still could be implemented. It will be used for Hash of matched type.
`Thread#hash` and `Signal#hash` is implemented as unseeded cause they are
 used before `StdHasher @@seed` is initialized.

Hash::Hasher is default hasher that uses `hash(hasher)` and it is used as
default seeded hasher.

Also, number normalization for hashing introduced, ie rule 'equality
forces hash equality' is forced (`a == b` => `a.hash == b.hash`).
Normalization idea is borrowed from Python implementation.
It fixes several issues with BigInt and BigFloat on 32bit platform,
but not all issues.

Fixes crystal-lang#4578
Fixes crystal-lang#3932
Prerequisite for crystal-lang#4557
Replaces crystal-lang#4581
Correlates with crystal-lang#4653
funny-falcon added a commit to funny-falcon/crystal that referenced this pull request Aug 24, 2017
Prepare hash infrastructor to future change of hashing algrorithm
to protect against Hash DoS.
Class|Struct should define method `def hash(hasher)` and call
`hasher << @ivar` inside.

As an option, for speed, and for backward compatibility, `def hash`
still could be implemented. It will be used for Hash of matched type.
`Thread#hash` and `Signal#hash` is implemented as unseeded cause they are
 used before `StdHasher @@seed` is initialized.

Hash::Hasher is default hasher that uses `hash(hasher)` and it is used as
default seeded hasher.

Also, number normalization for hashing introduced, ie rule 'equality
forces hash equality' is forced (`a == b` => `a.hash == b.hash`).
Normalization idea is borrowed from Python implementation.
It fixes several issues with BigInt and BigFloat on 32bit platform,
but not all issues.

Fixes crystal-lang#4578
Fixes crystal-lang#3932
Prerequisite for crystal-lang#4557
Replaces crystal-lang#4581
Correlates with crystal-lang#4653
funny-falcon added a commit to funny-falcon/crystal that referenced this pull request Sep 3, 2017
Prepare hash infrastructor to future change of hashing algrorithm
to protect against Hash DoS.
Class|Struct should define method `def hash(hasher)` and call
`hasher << @ivar` inside.

As an option, for speed, and for backward compatibility, `def hash`
still could be implemented. It will be used for Hash of matched type.
`Thread#hash` and `Signal#hash` is implemented as unseeded cause they are
 used before `StdHasher @@seed` is initialized.

Hash::Hasher is default hasher that uses `hash(hasher)` and it is used as
default seeded hasher.

Also, number normalization for hashing introduced, ie rule 'equality
forces hash equality' is forced (`a == b` => `a.hash == b.hash`).
Normalization idea is borrowed from Python implementation.
It fixes several issues with BigInt and BigFloat on 32bit platform,
but not all issues.

Fixes crystal-lang#4578
Fixes crystal-lang#3932
Prerequisite for crystal-lang#4557
Replaces crystal-lang#4581
Correlates with crystal-lang#4653
funny-falcon added a commit to funny-falcon/crystal that referenced this pull request Sep 3, 2017
Prepare hash infrastructor to future change of hashing algrorithm
to protect against Hash DoS.
Class|Struct should define method `def hash(hasher)` and call
`hasher << @ivar` inside.

As an option, for speed, and for backward compatibility, `def hash`
still could be implemented. It will be used for Hash of matched type.
`Thread#hash` and `Signal#hash` is implemented as unseeded cause they are
 used before `StdHasher @@seed` is initialized.

Hash::Hasher is default hasher that uses `hash(hasher)` and it is used as
default seeded hasher.

Also, number normalization for hashing introduced, ie rule 'equality
forces hash equality' is forced (`a == b` => `a.hash == b.hash`).
Normalization idea is borrowed from Python implementation.
It fixes several issues with BigInt and BigFloat on 32bit platform,
but not all issues.

Fixes crystal-lang#4578
Fixes crystal-lang#3932
Prerequisite for crystal-lang#4557
Replaces crystal-lang#4581
Correlates with crystal-lang#4653
funny-falcon added a commit to funny-falcon/crystal that referenced this pull request Sep 3, 2017
Prepare hash infrastructor to future change of hashing algrorithm
to protect against Hash DoS.
Class|Struct should define method `def hash(hasher)` and call
`hasher << @ivar` inside.

As an option, for speed, and for backward compatibility, `def hash`
still could be implemented. It will be used for Hash of matched type.
`Thread#hash` and `Signal#hash` is implemented as unseeded cause they are
 used before `StdHasher @@seed` is initialized.

Hash::Hasher is default hasher that uses `hash(hasher)` and it is used as
default seeded hasher.

Also, number normalization for hashing introduced, ie rule 'equality
forces hash equality' is forced (`a == b` => `a.hash == b.hash`).
Normalization idea is borrowed from Python implementation.
It fixes several issues with BigInt and BigFloat on 32bit platform,
but not all issues.

Fixes crystal-lang#4578
Fixes crystal-lang#3932
Prerequisite for crystal-lang#4557
Replaces crystal-lang#4581
Correlates with crystal-lang#4653
funny-falcon added a commit to funny-falcon/crystal that referenced this pull request Sep 3, 2017
Prepare hash infrastructor to future change of hashing algrorithm
to protect against Hash DoS.
Class|Struct should define method `def hash(hasher)` and call
`hasher << @ivar` inside.

As an option, for speed, and for backward compatibility, `def hash`
still could be implemented. It will be used for Hash of matched type.
`Thread#hash` and `Signal#hash` is implemented as unseeded cause they are
 used before `StdHasher @@seed` is initialized.

Hash::Hasher is default hasher that uses `hash(hasher)` and it is used as
default seeded hasher.

Also, number normalization for hashing introduced, ie rule 'equality
forces hash equality' is forced (`a == b` => `a.hash == b.hash`).
Normalization idea is borrowed from Python implementation.
It fixes several issues with BigInt and BigFloat on 32bit platform,
but not all issues.

Fixes crystal-lang#4578
Fixes crystal-lang#3932
Prerequisite for crystal-lang#4557
Replaces crystal-lang#4581
Correlates with crystal-lang#4653
funny-falcon added a commit to funny-falcon/crystal that referenced this pull request Sep 10, 2017
Prepare hash infrastructor to future change of hashing algrorithm
to protect against Hash DoS.
Class|Struct should define method `def hash(hasher)` and call
`hasher << @ivar` inside.

As an option, for speed, and for backward compatibility, `def hash`
still could be implemented. It will be used for Hash of matched type.
`Thread#hash` and `Signal#hash` is implemented as unseeded cause they are
 used before `StdHasher @@seed` is initialized.

Hash::Hasher is default hasher that uses `hash(hasher)` and it is used as
default seeded hasher.

Also, number normalization for hashing introduced, ie rule 'equality
forces hash equality' is forced (`a == b` => `a.hash == b.hash`).
Normalization idea is borrowed from Python implementation.
It fixes several issues with BigInt and BigFloat on 32bit platform,
but not all issues.

Fixes crystal-lang#4578
Fixes crystal-lang#3932
Prerequisite for crystal-lang#4557
Replaces crystal-lang#4581
Correlates with crystal-lang#4653
@akzhan akzhan mentioned this pull request Oct 8, 2017
akzhan added a commit to akzhan/crystal that referenced this pull request Nov 11, 2017
As declared by Crystal language reference, 1i32.hash should equal to 1f64.hash.

Extracted from crystal-lang#4675, also replaces crystal-lang#4581.
akzhan added a commit to akzhan/crystal that referenced this pull request Nov 11, 2017
As declared by Crystal language reference, 1i32.hash should equal to 1f64.hash.

Extracted from crystal-lang#4675, also replaces crystal-lang#4581.
akzhan added a commit to akzhan/crystal that referenced this pull request Nov 12, 2017
As declared by Crystal language reference, 1i32.hash should equal to 1f64.hash.

Extracted from crystal-lang#4675, also replaces crystal-lang#4581.
mverzilli pushed a commit that referenced this pull request Nov 24, 2017
* Introduces real Number normalization for Crystal::Hasher.

As declared by Crystal language reference, 1i32.hash should equal to 1f64.hash.

Extracted from #4675, also replaces #4581.

* hash specializations for BigInt, BigFloat, BigRational.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants