Import ahash-0.5.8

* Add Android.bp, OWNERS, METADATA and other 3p package required files.

Bug: 171754295
Test: build all rust crates.
Change-Id: I1d0c255b8e675cc73a5760f6b87bda3ed2540b7a
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
new file mode 100644
index 0000000..85cda19
--- /dev/null
+++ b/.cargo_vcs_info.json
@@ -0,0 +1,5 @@
+{
+  "git": {
+    "sha1": "1a39c02654da831a6b959ebcdb9314b35da3fa08"
+  }
+}
diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
new file mode 100644
index 0000000..01032fa
--- /dev/null
+++ b/.github/workflows/rust.yml
@@ -0,0 +1,120 @@
+name: Rust
+
+on: [push, pull_request]
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - name: Install latest stable
+        uses: actions-rs/toolchain@v1
+        with:
+            toolchain: stable
+            components: clippy
+      - name: check nostd
+        uses: actions-rs/cargo@v1
+        with:
+          command: check
+          args: --no-default-features
+      - name: test nostd
+        uses: actions-rs/cargo@v1
+        with:
+          command: test
+          args: --no-default-features
+      - name: check constrandom
+        uses: actions-rs/cargo@v1
+        with:
+          command: check
+          args: --no-default-features --features compile-time-rng
+      - name: test constrandom
+        uses: actions-rs/cargo@v1
+        with:
+          command: test
+          args: --no-default-features --features compile-time-rng
+      - name: check
+        uses: actions-rs/cargo@v1
+        with:
+          command: check
+      - name: test
+        uses: actions-rs/cargo@v1
+        with:
+          command: test
+      - name: Install latest nightly
+        uses: actions-rs/toolchain@v1
+        with:
+            toolchain: nightly
+            override: true
+            components: clippy
+      - name: check specialize
+        uses: actions-rs/cargo@v1
+        with:
+          command: check
+          args: --features specialize
+      - name: test specialize
+        uses: actions-rs/cargo@v1
+        with:
+          command: test
+          args: --features specialize
+  linux_arm7:
+    name: Linux ARMv7
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - uses: actions-rs/toolchain@v1
+        with:
+          toolchain: stable
+          target: armv7-unknown-linux-gnueabihf
+          override: true
+      - uses: actions-rs/cargo@v1
+        with:
+          use-cross: true
+          command: build
+          args: --target armv7-unknown-linux-gnueabihf
+  i686-unknown-linux-gnu:
+    name: Linux i686
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - uses: actions-rs/toolchain@v1
+        with:
+          toolchain: stable
+          target: i686-unknown-linux-gnu
+          override: true
+      - uses: actions-rs/cargo@v1
+        with:
+          use-cross: true
+          command: build
+          args: --target i686-unknown-linux-gnu
+  x86_64-unknown-linux-gnu:
+    name: Linux x86_64 - specialize
+    runs-on: ubuntu-latest
+    env:
+        RUSTFLAGS: -C target-feature=+aes
+    steps:
+      - uses: actions/checkout@v2
+      - uses: actions-rs/toolchain@v1
+        with:
+          toolchain: nightly
+          target: x86_64-unknown-linux-gnu
+          override: true
+      - uses: actions-rs/cargo@v1
+        with:
+          use-cross: true
+          command: build
+          args: --target x86_64-unknown-linux-gnu --features specialize
+  thumbv6m:
+    name: thumbv6m
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - uses: actions-rs/toolchain@v1
+        with:
+          toolchain: stable
+          target: thumbv6m-none-eabi
+          override: true
+      - uses: actions-rs/cargo@v1
+        with:
+          use-cross: true
+          command: check
+          args: --target thumbv6m-none-eabi --no-default-features
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..9bfbbd5
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,25 @@
+// This file is generated by cargo2android.py --device --run --dependencies.
+
+rust_library {
+    name: "libahash",
+    host_supported: true,
+    crate_name: "ahash",
+    srcs: ["src/lib.rs"],
+    edition: "2018",
+    features: [
+        "default",
+        "getrandom",
+        "lazy_static",
+        "std",
+    ],
+    rustlibs: [
+        "libgetrandom",
+        "liblazy_static",
+    ],
+}
+
+// dependent_library ["feature_list"]
+//   cfg-if-0.1.10
+//   getrandom-0.2.0
+//   lazy_static-1.4.0
+//   libc-0.2.80 "default,std"
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..caa382c
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,100 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies
+#
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
+[package]
+edition = "2018"
+name = "ahash"
+version = "0.5.8"
+authors = ["Tom Kaitchuck <Tom.Kaitchuck@gmail.com>"]
+description = "A non-cryptographic hash function using AES-NI for high performance"
+documentation = "https://docs.rs/ahash"
+readme = "README.md"
+keywords = ["hash", "hasher", "hashmap", "aes", "no-std"]
+categories = ["algorithms", "data-structures", "no-std"]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/tkaitchuck/ahash"
+[package.metadata.docs.rs]
+features = ["std"]
+rustc-args = ["-C", "target-feature=+aes"]
+rustdoc-args = ["-C", "target-feature=+aes"]
+[profile.bench]
+opt-level = 3
+lto = "fat"
+codegen-units = 1
+debug = false
+debug-assertions = false
+
+[profile.release]
+opt-level = 3
+lto = "fat"
+codegen-units = 1
+debug = false
+debug-assertions = false
+
+[profile.test]
+opt-level = 2
+lto = "fat"
+
+[lib]
+name = "ahash"
+path = "src/lib.rs"
+test = true
+doctest = true
+bench = true
+doc = true
+
+[[bench]]
+name = "ahash"
+path = "tests/bench.rs"
+harness = false
+
+[[bench]]
+name = "map"
+path = "tests/map_tests.rs"
+harness = false
+[dependencies.const-random]
+version = "0.1.6"
+optional = true
+
+[dependencies.getrandom]
+version = "0.2.0"
+optional = true
+
+[dependencies.lazy_static]
+version = "1.4.0"
+optional = true
+[dev-dependencies.criterion]
+version = "0.3.2"
+
+[dev-dependencies.fnv]
+version = "1.0.5"
+
+[dev-dependencies.fxhash]
+version = "0.2.1"
+
+[dev-dependencies.hex]
+version = "0.4.2"
+
+[dev-dependencies.no-panic]
+version = "0.1.10"
+
+[dev-dependencies.rand]
+version = "0.7.3"
+
+[dev-dependencies.seahash]
+version = "4.0"
+
+[features]
+compile-time-rng = ["const-random"]
+default = ["std"]
+specialize = []
+std = ["getrandom", "lazy_static"]
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
new file mode 100644
index 0000000..fb865fe
--- /dev/null
+++ b/Cargo.toml.orig
@@ -0,0 +1,80 @@
+[package]
+name = "ahash"
+version = "0.5.8"
+authors = ["Tom Kaitchuck <Tom.Kaitchuck@gmail.com>"]
+license = "MIT OR Apache-2.0"
+description = "A non-cryptographic hash function using AES-NI for high performance"
+documentation = "https://docs.rs/ahash"
+repository = "https://github.com/tkaitchuck/ahash"
+keywords = ["hash", "hasher", "hashmap", "aes", "no-std"]
+categories = ["algorithms", "data-structures", "no-std"]
+edition = "2018"
+readme = "README.md"
+
+[lib]
+name = "ahash"
+path = "src/lib.rs"
+test = true
+doctest = true
+bench = true
+doc = true
+
+[features]
+default = ["std"]
+
+# Enabling this will enable `AHashMap` and `AHashSet`, and runtime key generation.
+std = ["getrandom", "lazy_static"]
+
+# This is an alternitive to std which does compile time key generation so that the standard library is not required.
+# This implies the produced binary will not be identical. If both this and `std` are disabled constant keys are used.
+compile-time-rng = ["const-random"]
+
+# Enables specilization (requires nightly)
+specialize = []
+
+[[bench]]
+name = "ahash"
+path = "tests/bench.rs"
+harness = false
+
+[[bench]]
+name = "map"
+path = "tests/map_tests.rs"
+harness = false
+
+[profile.test]
+opt-level = 2
+lto = 'fat'
+
+[profile.release]
+opt-level = 3
+debug = false
+lto = 'fat'
+debug-assertions = false
+codegen-units = 1
+
+[profile.bench]
+opt-level = 3
+debug = false
+lto = 'fat'
+debug-assertions = false
+codegen-units = 1
+
+[dependencies]
+lazy_static = { version = "1.4.0", optional = true }
+getrandom = { version = "0.2.0", optional = true }
+const-random = { version = "0.1.6", optional = true }
+
+[dev-dependencies]
+no-panic = "0.1.10"
+criterion = {version =  "0.3.2"}
+seahash = "4.0"
+fnv = "1.0.5"
+fxhash = "0.2.1"
+hex = "0.4.2"
+rand = "0.7.3"
+
+[package.metadata.docs.rs]
+rustc-args = ["-C", "target-feature=+aes"]
+rustdoc-args = ["-C", "target-feature=+aes"]
+features = ["std"]
diff --git a/FAQ.md b/FAQ.md
new file mode 100644
index 0000000..73465e5
--- /dev/null
+++ b/FAQ.md
@@ -0,0 +1,112 @@
+## How does aHash prevent DOS attacks
+
+AHash is designed to [prevent an adversary that does not know the key from being able to create hash collisions or partial collisions.](https://github.com/tkaitchuck/aHash/wiki/How-aHash-is-resists-DOS-attacks)
+
+If you are a cryptographer and would like to help review aHash's algorithm, please post a comment [here](https://github.com/tkaitchuck/aHash/issues/11).
+
+In short, this is achieved by ensuring that:
+
+* aHash is designed to [resist differential crypto analysis](https://github.com/tkaitchuck/aHash/wiki/How-aHash-is-resists-DOS-attacks#differential-analysis). Meaning it should not be possible to devise a scheme to "cancel" out a modification of the internal state from a block of input via some corresponding change in a subsequent block of input.
+  * This is achieved by not performing any "premixing" - This reversible mixing gave previous hashes such as murmurhash confidence in their quality, but could be undone by a deliberate attack.
+  * Before it is used each chunk of input is "masked" such as by xoring it with an unpredictable value.
+* aHash obeys the '[strict avalanche criterion](https://en.wikipedia.org/wiki/Avalanche_effect#Strict_avalanche_criterion)':
+Each bit of input has the potential to flip every bit of the output.
+* Similarly, each bit in the key can affect every bit in the output.
+* Input bits never effect just one, or a very few, bits in intermediate state. This is specifically designed to prevent the sort of 
+[differential attacks launched by the sipHash authors](https://emboss.github.io/blog/2012/12/14/breaking-murmur-hash-flooding-dos-reloaded/) which cancel previous inputs.
+* The `finish` call at the end of the hash is designed to not expose individual bits of the internal state. 
+  * For example in the main algorithm 256bits of state and 256bits of keys are reduced to 64 total bits using 3 rounds of AES encryption. 
+Reversing this is more than non-trivial. Most of the information is by definition gone, and any given bit of the internal state is fully diffused across the output.
+* In both aHash and its fallback the internal state is divided into two halves which are updated by two unrelated techniques using the same input. - This means that if there is a way to attack one of them it likely won't be able to attack both of them at the same time.
+* It is deliberately difficult to 'chain' collisions. (This has been the major technique used to weaponize attacks on other hash functions)
+
+More details are available on [the wiki](https://github.com/tkaitchuck/aHash/wiki/How-aHash-is-resists-DOS-attacks).
+
+## Why not use a cryptographic hash in a hashmap.
+
+Cryptographic hashes are designed to make is nearly impossible to find two items that collide when the attacker has full control
+over the input. This has several implications:
+
+* They are very difficult to construct, and have to go to a lot of effort to ensure that collisions are not possible.
+* They have no notion of a 'key'. Rather, they are fully deterministic and provide exactly one hash for a given input.
+
+For a HashMap the requirements are different.
+
+* Speed is very important, especially for short inputs. Often the key for a HashMap is a single `u32` or similar, and to be effective
+the bucket that it should be hashed to needs to be computed in just a few CPU cycles.
+* A hashmap does not need to provide a hard and fast guarantee that no two inputs will ever collide. Hence, hashCodes are not 256bits 
+but are just 64 or 32 bits in length. Often the first thing done with the hashcode is to truncate it further to compute which among a few buckets should be used for a key. 
+  * Here collisions are expected, and a cheap to deal with provided there is no systematic way to generated huge numbers of values that all
+go to the same bucket.
+  * This also means that unlike a cryptographic hash partial collisions matter. It doesn't do a hashmap any good to produce a unique 256bit hash if
+the lower 12 bits are all the same. This means that even a provably irreversible hash would not offer protection from a DOS attack in a hashmap
+because an attacker can easily just brute force the bottom N bits.
+
+From a cryptography point of view, a hashmap needs something closer to a block cypher.
+Where the input can be quickly mixed in a way that cannot be reversed without knowing a key.
+
+## Why isn't aHash cryptographically secure
+
+It is not designed to be. 
+Attempting to use aHash as a secure hash will likely fail to hold up for several reasons:
+
+1. aHash relies on random keys which are assumed to not be observable by an attacker. For a cryptographic hash all inputs can be seen and controlled by the attacker.
+2. aHash has not yet gone through peer review, which is a pre-requisite for security critical algorithms.
+3. Because aHash uses reduced rounds of AES as opposed to the standard of 10. Things like the SQUARE attack apply to part of the internal state.
+(These are mitigated by other means to prevent producing collections, but would be a problem in other contexts).
+4. Like any cypher based hash, it will show certain statistical deviations from truly random output when comparing a (VERY) large number of hashes. 
+(By definition cyphers have fewer collisions than truly random data.)
+
+There are efforts to build a secure hash function that uses AES-NI for acceleration, but aHash is not one of them.
+
+## How is aHash so fast
+
+When it is available aHash uses AES rounds using the AES-NI instruction. AES-NI is very fast (on an intel i7-6700 it 
+is as fast as a 64 bit multiplication.) and handles 16 bytes of input at a time, while being a very strong permutation.
+
+This is obviously much faster than most standard approaches to hashing, and does a better job of scrambling data than most non-secure hashes.
+
+On an intel i7-6700 compiled on nightly Rust with flags `-C opt-level=3 -C target-cpu=native -C codegen-units=1`:
+
+| Input   | SipHash 1-3 time | FnvHash time|FxHash time| aHash time| aHash Fallback* |
+|----------------|-----------|-----------|-----------|-----------|---------------|
+| u8             | 9.3271 ns | 0.808 ns  | **0.594 ns**  | 0.7704 ns | 0.7664 ns |
+| u16            | 9.5139 ns | 0.803 ns  | **0.594 ns**  | 0.7653 ns | 0.7704 ns |
+| u32            | 9.1196 ns | 1.4424 ns | **0.594 ns**  | 0.7637 ns | 0.7712 ns |
+| u64            | 10.854 ns | 3.0484 ns | **0.628 ns**  | 0.7788 ns | 0.7888 ns |
+| u128           | 12.465 ns | 7.0728 ns | 0.799 ns  | **0.6174 ns** | 0.6250 ns |
+| 1 byte string  | 11.745 ns | 2.4743 ns | 2.4000 ns | **1.4921 ns** | 1.5861 ns |
+| 3 byte string  | 12.066 ns | 3.5221 ns | 2.9253 ns | **1.4745 ns** | 1.8518 ns |
+| 4 byte string  | 11.634 ns | 4.0770 ns | 1.8818 ns | **1.5206 ns** | 1.8924 ns |
+| 7 byte string  | 14.762 ns | 5.9780 ns | 3.2282 ns | **1.5207 ns** | 1.8933 ns |
+| 8 byte string  | 13.442 ns | 4.0535 ns | 2.9422 ns | **1.6262 ns** | 1.8929 ns |
+| 15 byte string | 16.880 ns | 8.3434 ns | 4.6070 ns | **1.6265 ns** | 1.7965 ns |
+| 16 byte string | 15.155 ns | 7.5796 ns | 3.2619 ns | **1.6262 ns** | 1.8011 ns |
+| 24 byte string | 16.521 ns | 12.492 ns | 3.5424 ns | **1.6266 ns** | 2.8311 ns |
+| 68 byte string | 24.598 ns | 50.715 ns | 5.8312 ns | **4.8282 ns** | 5.4824 ns |
+| 132 byte string| 39.224 ns | 119.96 ns | 11.777 ns | **6.5087 ns** | 9.1459 ns |
+|1024 byte string| 254.00 ns | 1087.3 ns | 156.41 ns | **25.402 ns** | 54.566 ns |
+
+* Fallback refers to the algorithm aHash would use if AES instructions are unavailable.
+For reference a hash that does nothing (not even reads the input data takes) **0.520 ns**. So that represents the fastest
+possible time.
+
+As you can see above aHash like `FxHash` provides a large speedup over `SipHash-1-3` which is already nearly twice as fast as `SipHash-2-4`.
+
+Rust's HashMap by default uses `SipHash-1-3` because faster hash functions such as `FxHash` are predictable and vulnerable to denial of
+service attacks. While `aHash` has both very strong scrambling and very high performance.
+
+AHash performs well when dealing with large inputs because aHash reads 8 or 16 bytes at a time. (depending on availability of AES-NI)
+
+Because of this, and its optimized logic, `aHash` is able to outperform `FxHash` with strings.
+It also provides especially good performance dealing with unaligned input.
+(Notice the big performance gaps between 3 vs 4, 7 vs 8 and 15 vs 16 in `FxHash` above)
+
+### Which CPUs can use the hardware acceleration
+
+Hardware AES instructions are built into Intel processors built after 2010 and AMD processors after 2012.
+It is also available on [many other CPUs](https://en.wikipedia.org/wiki/AES_instruction_set) should in eventually
+be able to get aHash to work. However, only X86 and X86-64 are the only supported architectures at the moment, as currently
+they are the only architectures for which Rust provides an intrinsic.
+
+aHash also uses `sse2` and `sse3` instructions. X86 processors that have `aesni` also have these instruction sets.
diff --git a/LICENSE b/LICENSE
new file mode 120000
index 0000000..6b579aa
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1 @@
+LICENSE-APACHE
\ No newline at end of file
diff --git a/LICENSE-APACHE b/LICENSE-APACHE
new file mode 100644
index 0000000..16fe87b
--- /dev/null
+++ b/LICENSE-APACHE
@@ -0,0 +1,201 @@
+                              Apache License
+                        Version 2.0, January 2004
+                     http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+   "License" shall mean the terms and conditions for use, reproduction,
+   and distribution as defined by Sections 1 through 9 of this document.
+
+   "Licensor" shall mean the copyright owner or entity authorized by
+   the copyright owner that is granting the License.
+
+   "Legal Entity" shall mean the union of the acting entity and all
+   other entities that control, are controlled by, or are under common
+   control with that entity. For the purposes of this definition,
+   "control" means (i) the power, direct or indirect, to cause the
+   direction or management of such entity, whether by contract or
+   otherwise, or (ii) ownership of fifty percent (50%) or more of the
+   outstanding shares, or (iii) beneficial ownership of such entity.
+
+   "You" (or "Your") shall mean an individual or Legal Entity
+   exercising permissions granted by this License.
+
+   "Source" form shall mean the preferred form for making modifications,
+   including but not limited to software source code, documentation
+   source, and configuration files.
+
+   "Object" form shall mean any form resulting from mechanical
+   transformation or translation of a Source form, including but
+   not limited to compiled object code, generated documentation,
+   and conversions to other media types.
+
+   "Work" shall mean the work of authorship, whether in Source or
+   Object form, made available under the License, as indicated by a
+   copyright notice that is included in or attached to the work
+   (an example is provided in the Appendix below).
+
+   "Derivative Works" shall mean any work, whether in Source or Object
+   form, that is based on (or derived from) the Work and for which the
+   editorial revisions, annotations, elaborations, or other modifications
+   represent, as a whole, an original work of authorship. For the purposes
+   of this License, Derivative Works shall not include works that remain
+   separable from, or merely link (or bind by name) to the interfaces of,
+   the Work and Derivative Works thereof.
+
+   "Contribution" shall mean any work of authorship, including
+   the original version of the Work and any modifications or additions
+   to that Work or Derivative Works thereof, that is intentionally
+   submitted to Licensor for inclusion in the Work by the copyright owner
+   or by an individual or Legal Entity authorized to submit on behalf of
+   the copyright owner. For the purposes of this definition, "submitted"
+   means any form of electronic, verbal, or written communication sent
+   to the Licensor or its representatives, including but not limited to
+   communication on electronic mailing lists, source code control systems,
+   and issue tracking systems that are managed by, or on behalf of, the
+   Licensor for the purpose of discussing and improving the Work, but
+   excluding communication that is conspicuously marked or otherwise
+   designated in writing by the copyright owner as "Not a Contribution."
+
+   "Contributor" shall mean Licensor and any individual or Legal Entity
+   on behalf of whom a Contribution has been received by Licensor and
+   subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   copyright license to reproduce, prepare Derivative Works of,
+   publicly display, publicly perform, sublicense, and distribute the
+   Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   (except as stated in this section) patent license to make, have made,
+   use, offer to sell, sell, import, and otherwise transfer the Work,
+   where such license applies only to those patent claims licensable
+   by such Contributor that are necessarily infringed by their
+   Contribution(s) alone or by combination of their Contribution(s)
+   with the Work to which such Contribution(s) was submitted. If You
+   institute patent litigation against any entity (including a
+   cross-claim or counterclaim in a lawsuit) alleging that the Work
+   or a Contribution incorporated within the Work constitutes direct
+   or contributory patent infringement, then any patent licenses
+   granted to You under this License for that Work shall terminate
+   as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+   Work or Derivative Works thereof in any medium, with or without
+   modifications, and in Source or Object form, provided that You
+   meet the following conditions:
+
+   (a) You must give any other recipients of the Work or
+       Derivative Works a copy of this License; and
+
+   (b) You must cause any modified files to carry prominent notices
+       stating that You changed the files; and
+
+   (c) You must retain, in the Source form of any Derivative Works
+       that You distribute, all copyright, patent, trademark, and
+       attribution notices from the Source form of the Work,
+       excluding those notices that do not pertain to any part of
+       the Derivative Works; and
+
+   (d) If the Work includes a "NOTICE" text file as part of its
+       distribution, then any Derivative Works that You distribute must
+       include a readable copy of the attribution notices contained
+       within such NOTICE file, excluding those notices that do not
+       pertain to any part of the Derivative Works, in at least one
+       of the following places: within a NOTICE text file distributed
+       as part of the Derivative Works; within the Source form or
+       documentation, if provided along with the Derivative Works; or,
+       within a display generated by the Derivative Works, if and
+       wherever such third-party notices normally appear. The contents
+       of the NOTICE file are for informational purposes only and
+       do not modify the License. You may add Your own attribution
+       notices within Derivative Works that You distribute, alongside
+       or as an addendum to the NOTICE text from the Work, provided
+       that such additional attribution notices cannot be construed
+       as modifying the License.
+
+   You may add Your own copyright statement to Your modifications and
+   may provide additional or different license terms and conditions
+   for use, reproduction, or distribution of Your modifications, or
+   for any such Derivative Works as a whole, provided Your use,
+   reproduction, and distribution of the Work otherwise complies with
+   the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+   any Contribution intentionally submitted for inclusion in the Work
+   by You to the Licensor shall be under the terms and conditions of
+   this License, without any additional terms or conditions.
+   Notwithstanding the above, nothing herein shall supersede or modify
+   the terms of any separate license agreement you may have executed
+   with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+   names, trademarks, service marks, or product names of the Licensor,
+   except as required for reasonable and customary use in describing the
+   origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+   agreed to in writing, Licensor provides the Work (and each
+   Contributor provides its Contributions) on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+   implied, including, without limitation, any warranties or conditions
+   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+   PARTICULAR PURPOSE. You are solely responsible for determining the
+   appropriateness of using or redistributing the Work and assume any
+   risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+   whether in tort (including negligence), contract, or otherwise,
+   unless required by applicable law (such as deliberate and grossly
+   negligent acts) or agreed to in writing, shall any Contributor be
+   liable to You for damages, including any direct, indirect, special,
+   incidental, or consequential damages of any character arising as a
+   result of this License or out of the use or inability to use the
+   Work (including but not limited to damages for loss of goodwill,
+   work stoppage, computer failure or malfunction, or any and all
+   other commercial damages or losses), even if such Contributor
+   has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+   the Work or Derivative Works thereof, You may choose to offer,
+   and charge a fee for, acceptance of support, warranty, indemnity,
+   or other liability obligations and/or rights consistent with this
+   License. However, in accepting such obligations, You may act only
+   on Your own behalf and on Your sole responsibility, not on behalf
+   of any other Contributor, and only if You agree to indemnify,
+   defend, and hold each Contributor harmless for any liability
+   incurred by, or claims asserted against, such Contributor by reason
+   of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+   To apply the Apache License to your work, attach the following
+   boilerplate notice, with the fields enclosed by brackets "[]"
+   replaced with your own identifying information. (Don't include
+   the brackets!)  The text should be enclosed in the appropriate
+   comment syntax for the file format. We also recommend that a
+   file or class name and description of purpose be included on the
+   same "printed page" as the copyright notice for easier
+   identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+	http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/LICENSE-MIT b/LICENSE-MIT
new file mode 100644
index 0000000..5afc2a7
--- /dev/null
+++ b/LICENSE-MIT
@@ -0,0 +1,25 @@
+Copyright (c) 2016 Amanieu d'Antras
+
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..150fb23
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,19 @@
+name: "ahash"
+description: "A non-cryptographic hash function using AES-NI for high performance"
+third_party {
+  url {
+    type: HOMEPAGE
+    value: "https://crates.io/crates/ahash"
+  }
+  url {
+    type: ARCHIVE
+    value: "https://static.crates.io/crates/ahash/ahash-0.5.8.crate"
+  }
+  version: "0.5.8"
+  license_type: NOTICE
+  last_upgrade_date {
+    year: 2020
+    month: 11
+    day: 9
+  }
+}
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_APACHE2
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..46fc303
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1 @@
+include platform/prebuilts/rust:/OWNERS
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..7f4ba36
--- /dev/null
+++ b/README.md
@@ -0,0 +1,106 @@
+# aHash     ![Build Status](https://img.shields.io/github/workflow/status/tkaitchuck/ahash/Rust) ![Licence](https://img.shields.io/crates/l/ahash) ![Downloads](https://img.shields.io/crates/d/ahash) 
+
+AHash is the [fastest](https://github.com/tkaitchuck/aHash/blob/master/compare/readme.md#Speed), 
+[DOS resistant hash](https://github.com/tkaitchuck/aHash/wiki/How-aHash-is-resists-DOS-attacks) currently available in Rust.
+AHash is intended *exclusively* for use in in-memory hashmaps. 
+
+AHash's output is of [high quality](https://github.com/tkaitchuck/aHash/blob/master/compare/readme.md#Quality) but aHash is **not** a cryptographically secure hash.
+
+## Design
+
+Because AHash is a keyed hash, each map will produce completely different hashes, which cannot be predicted without knowing the keys.
+[This prevents DOS attacks where an attacker sends a large number of items whose hashes collide that get used as keys in a hashmap.](https://github.com/tkaitchuck/aHash/wiki/How-aHash-is-resists-DOS-attacks)
+
+This also avoids [accidentally quadratic behavior by reading from one map and writing to another.](https://accidentallyquadratic.tumblr.com/post/153545455987/rust-hash-iteration-reinsertion)
+
+## Goals and Non-Goals
+
+AHash does *not* have a fixed standard for its output. This allows it to improve over time. For example,
+if any faster algorithm is found, aHash will be updated to incorporate the technique.
+Similarly, should any flaw in aHash's DOS resistance be found, aHash will be changed to correct the flaw.
+
+Because it does not have a fixed standard, different computers or computers on versions of the code will observe different hash values.
+As such aHash not recommended for use other than in-memory maps. Specifically, aHash is not intended for network use or in applications which persist hashed values.
+(In these cases `HighwayHash` would be a better choice)
+
+Additionally, aHash is not intended to be cryptographly secure and should not be used as a MAC, or anywhere which requires a cryptographically secure hash.
+(In these cases `SHA-3` would be a better choice)
+
+## Usage
+
+AHash is a drop in replacement for the default implementation of the `Hasher` trait. To construct a `HashMap` using aHash 
+its hasher do the following:
+
+```rust
+use ahash::{AHasher, RandomState};
+use std::collections::HashMap;
+
+let mut map: HashMap<i32, i32, RandomState> = HashMap::default();
+map.insert(12, 34);
+```
+For convinence wrappers called `AHashMap` and `AHashSet` are also provided.
+These to the same thing with slightly less typing.
+```rust
+use ahash::AHashMap;
+
+let mut map: AHashMap<i32, i32> = AHashMap::new();
+map.insert(12, 34);
+map.insert(56, 78);
+```
+
+## Flags
+
+The aHash package has three flags:
+* `std`: This enables features which require the standard library. (On by default) This includes generating random keys and providing the utility classes `AHashMap` and `AHashSet`.
+* `compile-time-rng`: As an alternative to `std` when it is not available, this generates Random numbers for keys at compile time. This allows for DOS resistance even if there is no random number generator available at runtime (assuming the compiled binary is not public).
+Note that this has the effect of making the output of the build non-deterministic. 
+* `specialize`: This uses the specialization feature to provide optimized algorithms for primitive types. (This requires nightly)
+
+**NOTE:** If neither `std` or `compile-time-rng` aHash will fall back on using the numeric value of memory addresses as a source of randomness.
+This is somewhat strong if ALSR is turned on (it is by default) but for some embedded platforms where this is not available,
+this will result in weak keys. As a result, it is strongly recommended to use `std` when it is available and `compile-time-rng` when developing for an embedded platform where `std` is not available.
+(If both are enabled `std` will take precedence and `compile-time-rng` will have no effect.)
+
+
+## Comparison with other hashers
+
+A full comparison with other hashing algorithms can be found [here](https://github.com/tkaitchuck/aHash/blob/master/compare/readme.md)
+
+![Hasher perfromance](https://docs.google.com/spreadsheets/d/e/2PACX-1vSK7Li2nS-Bur9arAYF9IfT37MP-ohAe1v19lZu5fd9MajI1fSveLAQZyEie4Ea9k5-SWHTff7nL2DW/pubchart?oid=1323618938&format=image)
+
+For more a more representative performance comparison which includes the overhead of using a HashMap, see [HashBrown's benchmarks](https://github.com/rust-lang/hashbrown#performance)
+as HashBrown now uses aHash as its hasher by default.
+
+## Hash quality
+
+AHash passes the full [SMHasher test suite](https://github.com/rurban/smhasher). 
+
+The code to reproduce the result, and the full output [are checked into the repo](https://github.com/tkaitchuck/aHash/tree/master/smhasher).
+
+## Additional FAQ
+
+A separate FAQ document is maintained [here](https://github.com/tkaitchuck/aHash/blob/master/FAQ.md). 
+If you have questions not covered there, open an issue [here](https://github.com/tkaitchuck/aHash/issues).
+
+## License
+
+Licensed under either of:
+
+ * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
+ * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
+
+at your option.
+
+## Contribution
+
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
+additional terms or conditions.
+
+
+
+
+
+
+
+
diff --git a/rustfmt.toml b/rustfmt.toml
new file mode 100644
index 0000000..7530651
--- /dev/null
+++ b/rustfmt.toml
@@ -0,0 +1 @@
+max_width = 120
diff --git a/smhasher/0001-Add-support-for-aHash.patch b/smhasher/0001-Add-support-for-aHash.patch
new file mode 100644
index 0000000..99a98d3
--- /dev/null
+++ b/smhasher/0001-Add-support-for-aHash.patch
@@ -0,0 +1,135 @@
+From 426384ce34cf410d892eeeeeb7f6046d52bff8e7 Mon Sep 17 00:00:00 2001
+From: Tom Kaitchuck <Tom.Kaitchuck@gmail.com>
+Date: Sat, 11 Jul 2020 17:15:56 -0700
+Subject: [PATCH] Add support for ahash
+
+---
+ CMakeLists.txt |  1 +
+ Hashes.h       |  5 +++++
+ ahash.h        | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
+ main.cpp       |  2 +-
+ 4 files changed, 55 insertions(+), 1 deletion(-)
+ create mode 100644 ahash.h
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 6ebab1a..9d79e98 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -470,10 +470,11 @@ add_executable(
+ target_link_libraries(
+   SMHasher
+   SMHasherSupport
+   ${HIGHWAY_LIB}
+   ${BLAKE3_LIB}
++  libahash_c.a
+   ${CMAKE_THREAD_LIBS_INIT}
+   )
+ 
+ #add_executable(
+ #  bittest
+diff --git a/Hashes.h b/Hashes.h
+index 4e111c1..fcd3e38 100644
+--- a/Hashes.h
++++ b/Hashes.h
+@@ -19,10 +19,11 @@
+ #if defined(__SSE4_2__) && defined(__x86_64__)
+ #include "metrohash/metrohash64crc.h"
+ #include "metrohash/metrohash128crc.h"
+ #endif
+ 
++#include "ahash.h"
+ #include "fasthash.h"
+ #include "jody_hash32.h"
+ #include "jody_hash64.h"
+ 
+ // objsize: 0-0x113 = 276
+@@ -356,10 +357,14 @@ inline void fasthash32_test ( const void * key, int len, uint32_t seed, void * o
+ }
+ #ifdef HAVE_INT64
+ inline void fasthash64_test ( const void * key, int len, uint32_t seed, void * out ) {
+   *(uint64_t*)out = fasthash64(key, (size_t) len, (uint64_t)seed);
+ }
++inline void ahash64_test ( const void * key, int len, uint32_t seed, void * out ) {
++  *(uint64_t*)out = ahash64(key, (size_t) len, (uint64_t)seed);
++}
++
+ #endif
+ 
+ // objsize 0-778: 1912
+ void mum_hash_test(const void * key, int len, uint32_t seed, void * out);
+ 
+diff --git a/ahash.h b/ahash.h
+new file mode 100644
+index 0000000..6c59caf
+--- /dev/null
++++ b/ahash.h
+@@ -0,0 +1,48 @@
++/* The MIT License
++
++   Copyright (C) 2012 Zilong Tan (eric.zltan@gmail.com)
++
++   Permission is hereby granted, free of charge, to any person
++   obtaining a copy of this software and associated documentation
++   files (the "Software"), to deal in the Software without
++   restriction, including without limitation the rights to use, copy,
++   modify, merge, publish, distribute, sublicense, and/or sell copies
++   of the Software, and to permit persons to whom the Software is
++   furnished to do so, subject to the following conditions:
++
++   The above copyright notice and this permission notice shall be
++   included in all copies or substantial portions of the Software.
++
++   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
++   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
++   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
++   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
++   SOFTWARE.
++*/
++
++#ifndef _AHASH_H
++#define _AHASH_H
++
++#include <stdint.h>
++#include <stdio.h>
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++/**
++ * Ahash - 64-bit implementation of aHash
++ * @buf:  data buffer
++ * @len:  data size
++ * @seed: the seed
++ */
++       uint64_t ahash64(const void *buf, size_t len, uint64_t seed);
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif
+\ No newline at end of file
+diff --git a/main.cpp b/main.cpp
+index 04060f2..7489aaf 100644
+--- a/main.cpp
++++ b/main.cpp
+@@ -263,11 +263,11 @@ HashInfo g_hashes[] =
+ 
+   { xxh3_test,            64, 0x39CD9E4A, "xxh3",        "xxHash v3, 64-bit", GOOD },
+   { xxh3low_test,         32, 0xFAE8467B, "xxh3low",     "xxHash v3, 64-bit, low 32-bits part", GOOD },
+   { xxh128_test,         128, 0xEB61B3A0, "xxh128",      "xxHash v3, 128-bit", GOOD },
+   { xxh128low_test,       64, 0x54D1CC70, "xxh128low",   "xxHash v3, 128-bit, low 64-bits part", GOOD },
+-
++  { ahash64_test,         64, 0x00000000, "ahash64",  "ahash 64bit", GOOD }, //Expected value set to zero because aHash does not adhere to a fixed output.
+ #if __WORDSIZE >= 64
+ # define TIFU_VERIF       0x644236D4
+ #else
+   // broken on certain travis
+ # define TIFU_VERIF       0x0
+-- 
+2.25.1
+
diff --git a/smhasher/ahashOutput.txt b/smhasher/ahashOutput.txt
new file mode 100644
index 0000000..f618f2c
--- /dev/null
+++ b/smhasher/ahashOutput.txt
@@ -0,0 +1,1467 @@
+-------------------------------------------------------------------------------
+--- Testing ahash64 "ahash 64bit" GOOD
+
+[[[ Sanity Tests ]]]
+
+Verification value 0x64556379 ....... SKIP (self- or unseeded)
+Running sanity check 1     .......... PASS
+Running AppendedZeroesTest .......... PASS
+
+[[[ Speed Tests ]]]
+
+Bulk speed test - 262144-byte keys
+Alignment  7 - 19.381 bytes/cycle - 55448.94 MiB/sec @ 3 ghz
+Alignment  6 - 19.351 bytes/cycle - 55363.53 MiB/sec @ 3 ghz
+Alignment  5 - 19.357 bytes/cycle - 55380.15 MiB/sec @ 3 ghz
+Alignment  4 - 19.332 bytes/cycle - 55308.08 MiB/sec @ 3 ghz
+Alignment  3 - 19.296 bytes/cycle - 55206.94 MiB/sec @ 3 ghz
+Alignment  2 - 19.326 bytes/cycle - 55292.64 MiB/sec @ 3 ghz
+Alignment  1 - 19.336 bytes/cycle - 55322.04 MiB/sec @ 3 ghz
+Alignment  0 - 20.429 bytes/cycle - 58448.30 MiB/sec @ 3 ghz
+Average      - 19.476 bytes/cycle - 55721.33 MiB/sec @ 3 ghz
+
+Small key speed test -    1-byte keys -    23.00 cycles/hash
+Small key speed test -    2-byte keys -    23.13 cycles/hash
+Small key speed test -    3-byte keys -    24.21 cycles/hash
+Small key speed test -    4-byte keys -    24.00 cycles/hash
+Small key speed test -    5-byte keys -    25.18 cycles/hash
+Small key speed test -    6-byte keys -    25.02 cycles/hash
+Small key speed test -    7-byte keys -    25.20 cycles/hash
+Small key speed test -    8-byte keys -    27.75 cycles/hash
+Small key speed test -    9-byte keys -    24.22 cycles/hash
+Small key speed test -   10-byte keys -    24.00 cycles/hash
+Small key speed test -   11-byte keys -    24.16 cycles/hash
+Small key speed test -   12-byte keys -    24.04 cycles/hash
+Small key speed test -   13-byte keys -    24.00 cycles/hash
+Small key speed test -   14-byte keys -    24.00 cycles/hash
+Small key speed test -   15-byte keys -    24.07 cycles/hash
+Small key speed test -   16-byte keys -    24.26 cycles/hash
+Small key speed test -   17-byte keys -    26.00 cycles/hash
+Small key speed test -   18-byte keys -    26.43 cycles/hash
+Small key speed test -   19-byte keys -    26.03 cycles/hash
+Small key speed test -   20-byte keys -    26.38 cycles/hash
+Small key speed test -   21-byte keys -    26.06 cycles/hash
+Small key speed test -   22-byte keys -    26.24 cycles/hash
+Small key speed test -   23-byte keys -    26.00 cycles/hash
+Small key speed test -   24-byte keys -    25.99 cycles/hash
+Small key speed test -   25-byte keys -    26.00 cycles/hash
+Small key speed test -   26-byte keys -    25.99 cycles/hash
+Small key speed test -   27-byte keys -    26.20 cycles/hash
+Small key speed test -   28-byte keys -    25.98 cycles/hash
+Small key speed test -   29-byte keys -    26.29 cycles/hash
+Small key speed test -   30-byte keys -    25.99 cycles/hash
+Small key speed test -   31-byte keys -    26.29 cycles/hash
+Average                                    25.229 cycles/hash
+
+[[[ 'Hashmap' Speed Tests ]]]
+
+std::unordered_map
+Init std HashMapTest:     289.522 cycles/op (102401 inserts, 1% deletions)
+Running std HashMapTest:  122.314 cycles/op (5.1 stdv)
+
+greg7mdp/parallel-hashmap
+Init fast HashMapTest:    110.898 cycles/op (102401 inserts, 1% deletions)
+Running fast HashMapTest: 83.840 cycles/op (3.3 stdv)  ....... PASS
+
+[[[ Avalanche Tests ]]]
+
+Testing   24-bit keys ->  64-bit hashes, 300000 reps worst bias is 0.597333%
+Testing   32-bit keys ->  64-bit hashes, 300000 reps worst bias is 0.618667%
+Testing   40-bit keys ->  64-bit hashes, 300000 reps worst bias is 0.602667%
+Testing   48-bit keys ->  64-bit hashes, 300000 reps worst bias is 0.626667%
+Testing   56-bit keys ->  64-bit hashes, 300000 reps worst bias is 0.715333%
+Testing   64-bit keys ->  64-bit hashes, 300000 reps worst bias is 0.648667%
+Testing   72-bit keys ->  64-bit hashes, 300000 reps worst bias is 0.809333%
+Testing   80-bit keys ->  64-bit hashes, 300000 reps worst bias is 0.654000%
+Testing   96-bit keys ->  64-bit hashes, 300000 reps worst bias is 0.679333%
+Testing  112-bit keys ->  64-bit hashes, 300000 reps worst bias is 0.668000%
+Testing  128-bit keys ->  64-bit hashes, 300000 reps worst bias is 0.769333%
+Testing  160-bit keys ->  64-bit hashes, 300000 reps worst bias is 0.675333%
+Testing  512-bit keys ->  64-bit hashes, 300000 reps worst bias is 0.806667%
+Testing 1024-bit keys ->  64-bit hashes, 300000 reps worst bias is 0.826667%
+
+[[[ Keyset 'Sparse' Tests ]]]
+
+Keyset 'Sparse' - 16-bit keys with up to 9 bits set - 50643 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected          0.6, actual      1 (1.67x) (1)
+Testing collisions (high 19-26 bits) - Worst is 21 bits: 619/1222 (0.51x)
+Testing collisions (high 12-bit) - Expected      50643.0, actual  46547 (0.92x)
+Testing collisions (high  8-bit) - Expected      50643.0, actual  50387 (0.99x) (-256)
+Testing collisions (low  32-bit) - Expected          0.6, actual      0 (0.00x)
+Testing collisions (low  19-26 bits) - Worst is 20 bits: 1256/2445 (0.51x)
+Testing collisions (low  12-bit) - Expected      50643.0, actual  46547 (0.92x)
+Testing collisions (low   8-bit) - Expected      50643.0, actual  50387 (0.99x) (-256)
+Testing distribution - Worst bias is the 13-bit window at bit 44 - 0.509%
+
+Keyset 'Sparse' - 24-bit keys with up to 8 bits set - 1271626 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected        376.5, actual    169 (0.45x)
+Testing collisions (high 24-36 bits) - Worst is 28 bits: 3066/6023 (0.51x)
+Testing collisions (high 12-bit) - Expected    1271626.0, actual 1267530 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    1271626.0, actual 1271370 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected        376.5, actual    193 (0.51x)
+Testing collisions (low  24-36 bits) - Worst is 36 bits: 13/23 (0.55x)
+Testing collisions (low  12-bit) - Expected    1271626.0, actual 1267530 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    1271626.0, actual 1271370 (1.00x) (-256)
+Testing distribution - Worst bias is the 17-bit window at bit 42 - 0.090%
+
+Keyset 'Sparse' - 32-bit keys with up to 7 bits set - 4514873 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       4746.0, actual   2349 (0.49x)
+Testing collisions (high 26-39 bits) - Worst is 33 bits: 1211/2373 (0.51x)
+Testing collisions (high 12-bit) - Expected    4514873.0, actual 4510777 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    4514873.0, actual 4514617 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       4746.0, actual   2291 (0.48x)
+Testing collisions (low  26-39 bits) - Worst is 29 bits: 18953/37968 (0.50x)
+Testing collisions (low  12-bit) - Expected    4514873.0, actual 4510777 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    4514873.0, actual 4514617 (1.00x) (-256)
+Testing distribution - Worst bias is the 19-bit window at bit 58 - 0.042%
+
+Keyset 'Sparse' - 40-bit keys with up to 6 bits set - 4598479 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       4923.4, actual   2464 (0.50x)
+Testing collisions (high 26-39 bits) - Worst is 37 bits: 86/153 (0.56x)
+Testing collisions (high 12-bit) - Expected    4598479.0, actual 4594383 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    4598479.0, actual 4598223 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       4923.4, actual   2396 (0.49x)
+Testing collisions (low  26-39 bits) - Worst is 39 bits: 24/38 (0.62x)
+Testing collisions (low  12-bit) - Expected    4598479.0, actual 4594383 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    4598479.0, actual 4598223 (1.00x) (-256)
+Testing distribution - Worst bias is the 19-bit window at bit 13 - 0.035%
+
+Keyset 'Sparse' - 48-bit keys with up to 6 bits set - 14196869 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      46927.3, actual  23526 (0.50x)
+Testing collisions (high 28-43 bits) - Worst is 40 bits: 94/183 (0.51x)
+Testing collisions (high 12-bit) - Expected   14196869.0, actual 14192773 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected   14196869.0, actual 14196613 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      46927.3, actual  23571 (0.50x)
+Testing collisions (low  28-43 bits) - Worst is 43 bits: 13/22 (0.57x)
+Testing collisions (low  12-bit) - Expected   14196869.0, actual 14192773 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected   14196869.0, actual 14196613 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 24 - 0.021%
+
+Keyset 'Sparse' - 56-bit keys with up to 5 bits set - 4216423 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       4139.3, actual   2005 (0.48x)
+Testing collisions (high 26-39 bits) - Worst is 29 bits: 16547/33114 (0.50x)
+Testing collisions (high 12-bit) - Expected    4216423.0, actual 4212327 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    4216423.0, actual 4216167 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       4139.3, actual   2099 (0.51x)
+Testing collisions (low  26-39 bits) - Worst is 32 bits: 2099/4139 (0.51x)
+Testing collisions (low  12-bit) - Expected    4216423.0, actual 4212327 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    4216423.0, actual 4216167 (1.00x) (-256)
+Testing distribution - Worst bias is the 19-bit window at bit 31 - 0.057%
+
+Keyset 'Sparse' - 64-bit keys with up to 5 bits set - 8303633 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      16053.7, actual   7962 (0.50x)
+Testing collisions (high 27-41 bits) - Worst is 39 bits: 78/125 (0.62x)
+Testing collisions (high 12-bit) - Expected    8303633.0, actual 8299537 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    8303633.0, actual 8303377 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      16053.7, actual   8118 (0.51x)
+Testing collisions (low  27-41 bits) - Worst is 38 bits: 140/250 (0.56x)
+Testing collisions (low  12-bit) - Expected    8303633.0, actual 8299537 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    8303633.0, actual 8303377 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit  7 - 0.037%
+
+Keyset 'Sparse' - 72-bit keys with up to 5 bits set - 15082603 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      52965.5, actual  26838 (0.51x)
+Testing collisions (high 28-43 bits) - Worst is 43 bits: 17/25 (0.66x)
+Testing collisions (high 12-bit) - Expected   15082603.0, actual 15078507 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected   15082603.0, actual 15082347 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      52965.5, actual  26568 (0.50x)
+Testing collisions (low  28-43 bits) - Worst is 36 bits: 1703/3310 (0.51x)
+Testing collisions (low  12-bit) - Expected   15082603.0, actual 15078507 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected   15082603.0, actual 15082347 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 20 - 0.029%
+
+Keyset 'Sparse' - 96-bit keys with up to 4 bits set - 3469497 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       2802.7, actual   1368 (0.49x)
+Testing collisions (high 26-39 bits) - Worst is 38 bits: 36/43 (0.82x)
+Testing collisions (high 12-bit) - Expected    3469497.0, actual 3465401 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    3469497.0, actual 3469241 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       2802.7, actual   1366 (0.49x)
+Testing collisions (low  26-39 bits) - Worst is 36 bits: 88/175 (0.50x)
+Testing collisions (low  12-bit) - Expected    3469497.0, actual 3465401 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    3469497.0, actual 3469241 (1.00x) (-256)
+Testing distribution - Worst bias is the 19-bit window at bit 16 - 0.080%
+
+Keyset 'Sparse' - 160-bit keys with up to 4 bits set - 26977161 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected     169446.5, actual  84423 (0.50x)
+Testing collisions (high 29-45 bits) - Worst is 43 bits: 51/82 (0.62x)
+Testing collisions (high 12-bit) - Expected   26977161.0, actual 26973065 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected   26977161.0, actual 26976905 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected     169446.5, actual  84652 (0.50x)
+Testing collisions (low  29-45 bits) - Worst is 45 bits: 15/20 (0.73x)
+Testing collisions (low  12-bit) - Expected   26977161.0, actual 26973065 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected   26977161.0, actual 26976905 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 20 - 0.010%
+
+Keyset 'Sparse' - 256-bit keys with up to 3 bits set - 2796417 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1820.7, actual    893 (0.49x)
+Testing collisions (high 25-38 bits) - Worst is 37 bits: 36/56 (0.63x)
+Testing collisions (high 12-bit) - Expected    2796417.0, actual 2792321 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2796417.0, actual 2796161 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1820.7, actual    946 (0.52x)
+Testing collisions (low  25-38 bits) - Worst is 37 bits: 32/56 (0.56x)
+Testing collisions (low  12-bit) - Expected    2796417.0, actual 2792321 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2796417.0, actual 2796161 (1.00x) (-256)
+Testing distribution - Worst bias is the 19-bit window at bit 29 - 0.120%
+
+Keyset 'Sparse' - 512-bit keys with up to 3 bits set - 22370049 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected     116512.9, actual  58551 (0.50x)
+Testing collisions (high 28-44 bits) - Worst is 42 bits: 59/113 (0.52x)
+Testing collisions (high 12-bit) - Expected   22370049.0, actual 22365953 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected   22370049.0, actual 22369793 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected     116512.9, actual  58363 (0.50x)
+Testing collisions (low  28-44 bits) - Worst is 40 bits: 238/455 (0.52x)
+Testing collisions (low  12-bit) - Expected   22370049.0, actual 22365953 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected   22370049.0, actual 22369793 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 39 - 0.015%
+
+Keyset 'Sparse' - 1024-bit keys with up to 2 bits set - 524801 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected         64.1, actual     34 (0.53x)
+Testing collisions (high 23-33 bits) - Worst is 30 bits: 147/256 (0.57x)
+Testing collisions (high 12-bit) - Expected     524801.0, actual 520705 (0.99x) (-4096)
+Testing collisions (high  8-bit) - Expected     524801.0, actual 524545 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected         64.1, actual     35 (0.55x)
+Testing collisions (low  23-33 bits) - Worst is 33 bits: 22/32 (0.69x)
+Testing collisions (low  12-bit) - Expected     524801.0, actual 520705 (0.99x) (-4096)
+Testing collisions (low   8-bit) - Expected     524801.0, actual 524545 (1.00x) (-256)
+Testing distribution - Worst bias is the 16-bit window at bit 29 - 0.187%
+
+Keyset 'Sparse' - 2048-bit keys with up to 2 bits set - 2098177 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1025.0, actual    487 (0.48x)
+Testing collisions (high 25-37 bits) - Worst is 36 bits: 38/64 (0.59x)
+Testing collisions (high 12-bit) - Expected    2098177.0, actual 2094081 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2098177.0, actual 2097921 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1025.0, actual    477 (0.47x)
+Testing collisions (low  25-37 bits) - Worst is 30 bits: 2058/4100 (0.50x)
+Testing collisions (low  12-bit) - Expected    2098177.0, actual 2094081 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2098177.0, actual 2097921 (1.00x) (-256)
+Testing distribution - Worst bias is the 18-bit window at bit 59 - 0.078%
+
+
+[[[ Keyset 'Permutation' Tests ]]]
+
+Combination Lowbits Tests:
+Keyset 'Combination' - up to 7 blocks from a set of 8 - 2396744 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1337.5, actual    700 (0.52x)
+Testing collisions (high 25-38 bits) - Worst is 38 bits: 15/20 (0.72x)
+Testing collisions (high 12-bit) - Expected    2396744.0, actual 2392648 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2396744.0, actual 2396488 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1337.5, actual    695 (0.52x)
+Testing collisions (low  25-38 bits) - Worst is 32 bits: 695/1337 (0.52x)
+Testing collisions (low  12-bit) - Expected    2396744.0, actual 2392648 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2396744.0, actual 2396488 (1.00x) (-256)
+Testing distribution - Worst bias is the 18-bit window at bit 25 - 0.078%
+
+
+Combination Highbits Tests
+Keyset 'Combination' - up to 7 blocks from a set of 8 - 2396744 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1337.5, actual    653 (0.49x)
+Testing collisions (high 25-38 bits) - Worst is 29 bits: 5394/10699 (0.50x)
+Testing collisions (high 12-bit) - Expected    2396744.0, actual 2392648 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2396744.0, actual 2396488 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1337.5, actual    644 (0.48x)
+Testing collisions (low  25-38 bits) - Worst is 31 bits: 1325/2674 (0.50x)
+Testing collisions (low  12-bit) - Expected    2396744.0, actual 2392648 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2396744.0, actual 2396488 (1.00x) (-256)
+Testing distribution - Worst bias is the 17-bit window at bit 18 - 0.038%
+
+
+Combination Hi-Lo Tests:
+Keyset 'Combination' - up to 6 blocks from a set of 15 - 12204240 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      34678.6, actual  17516 (0.51x)
+Testing collisions (high 27-42 bits) - Worst is 42 bits: 20/33 (0.59x)
+Testing collisions (high 12-bit) - Expected   12204240.0, actual 12200144 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected   12204240.0, actual 12203984 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      34678.6, actual  17293 (0.50x)
+Testing collisions (low  27-42 bits) - Worst is 42 bits: 21/33 (0.62x)
+Testing collisions (low  12-bit) - Expected   12204240.0, actual 12200144 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected   12204240.0, actual 12203984 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 38 - 0.022%
+
+
+Combination 0x8000000 Tests:
+Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      16384.0, actual   8370 (0.51x)
+Testing collisions (high 27-41 bits) - Worst is 40 bits: 43/63 (0.67x)
+Testing collisions (high 12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      16384.0, actual   8184 (0.50x)
+Testing collisions (low  27-41 bits) - Worst is 40 bits: 37/63 (0.58x)
+Testing collisions (low  12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 13 - 0.038%
+
+
+Combination 0x0000001 Tests:
+Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      16384.0, actual   8150 (0.50x)
+Testing collisions (high 27-41 bits) - Worst is 34 bits: 2047/4095 (0.50x)
+Testing collisions (high 12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      16384.0, actual   8264 (0.50x)
+Testing collisions (low  27-41 bits) - Worst is 37 bits: 273/511 (0.53x)
+Testing collisions (low  12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 18 - 0.038%
+
+
+Combination 0x800000000000000 Tests:
+Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      16384.0, actual   8130 (0.50x)
+Testing collisions (high 27-41 bits) - Worst is 38 bits: 141/255 (0.55x)
+Testing collisions (high 12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      16384.0, actual   8166 (0.50x)
+Testing collisions (low  27-41 bits) - Worst is 41 bits: 22/31 (0.69x)
+Testing collisions (low  12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 31 - 0.026%
+
+
+Combination 0x000000000000001 Tests:
+Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      16384.0, actual   8245 (0.50x)
+Testing collisions (high 27-41 bits) - Worst is 39 bits: 78/127 (0.61x)
+Testing collisions (high 12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      16384.0, actual   8289 (0.51x)
+Testing collisions (low  27-41 bits) - Worst is 37 bits: 274/511 (0.54x)
+Testing collisions (low  12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing distribution - Worst bias is the 19-bit window at bit 17 - 0.033%
+
+
+Combination 16-bytes [0-1] Tests:
+Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      16384.0, actual   8185 (0.50x)
+Testing collisions (high 27-41 bits) - Worst is 41 bits: 28/31 (0.88x)
+Testing collisions (high 12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      16384.0, actual   8232 (0.50x)
+Testing collisions (low  27-41 bits) - Worst is 38 bits: 152/255 (0.59x)
+Testing collisions (low  12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 27 - 0.024%
+
+
+Combination 16-bytes [0-last] Tests:
+Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      16384.0, actual   8107 (0.49x)
+Testing collisions (high 27-41 bits) - Worst is 34 bits: 2065/4095 (0.50x)
+Testing collisions (high 12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      16384.0, actual   8082 (0.49x)
+Testing collisions (low  27-41 bits) - Worst is 39 bits: 67/127 (0.52x)
+Testing collisions (low  12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 23 - 0.044%
+
+
+Combination 32-bytes [0-1] Tests:
+Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      16384.0, actual   8127 (0.50x)
+Testing collisions (high 27-41 bits) - Worst is 41 bits: 25/31 (0.78x)
+Testing collisions (high 12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      16384.0, actual   8238 (0.50x)
+Testing collisions (low  27-41 bits) - Worst is 38 bits: 150/255 (0.59x)
+Testing collisions (low  12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit  3 - 0.045%
+
+
+Combination 32-bytes [0-last] Tests:
+Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      16384.0, actual   8193 (0.50x)
+Testing collisions (high 27-41 bits) - Worst is 35 bits: 1079/2047 (0.53x)
+Testing collisions (high 12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      16384.0, actual   8201 (0.50x)
+Testing collisions (low  27-41 bits) - Worst is 41 bits: 18/31 (0.56x)
+Testing collisions (low  12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 26 - 0.036%
+
+
+Combination 64-bytes [0-1] Tests:
+Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      16384.0, actual   8169 (0.50x)
+Testing collisions (high 27-41 bits) - Worst is 39 bits: 72/127 (0.56x)
+Testing collisions (high 12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      16384.0, actual   8101 (0.49x)
+Testing collisions (low  27-41 bits) - Worst is 29 bits: 65198/131071 (0.50x)
+Testing collisions (low  12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 27 - 0.022%
+
+
+Combination 64-bytes [0-last] Tests:
+Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      16384.0, actual   8175 (0.50x)
+Testing collisions (high 27-41 bits) - Worst is 40 bits: 39/63 (0.61x)
+Testing collisions (high 12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      16384.0, actual   8220 (0.50x)
+Testing collisions (low  27-41 bits) - Worst is 39 bits: 83/127 (0.65x)
+Testing collisions (low  12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 24 - 0.035%
+
+
+Combination 128-bytes [0-1] Tests:
+Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      16384.0, actual   8183 (0.50x)
+Testing collisions (high 27-41 bits) - Worst is 36 bits: 532/1023 (0.52x)
+Testing collisions (high 12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      16384.0, actual   8309 (0.51x)
+Testing collisions (low  27-41 bits) - Worst is 41 bits: 18/31 (0.56x)
+Testing collisions (low  12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 33 - 0.040%
+
+
+Combination 128-bytes [0-last] Tests:
+Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      16384.0, actual   8280 (0.51x)
+Testing collisions (high 27-41 bits) - Worst is 40 bits: 41/63 (0.64x)
+Testing collisions (high 12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      16384.0, actual   8222 (0.50x)
+Testing collisions (low  27-41 bits) - Worst is 40 bits: 37/63 (0.58x)
+Testing collisions (low  12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 27 - 0.052%
+
+
+[[[ Keyset 'Window' Tests ]]]
+
+Keyset 'Window' -  32-bit key,  25-bit window - 32 tests, 33554432 keys per test
+Window at   0 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at   1 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at   2 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at   3 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at   4 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at   5 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at   6 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at   7 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at   8 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at   9 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  10 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  11 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  12 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  13 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  14 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  15 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  16 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  17 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  18 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  19 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  20 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  21 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  22 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  23 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  24 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  25 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  26 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  27 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  28 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  29 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  30 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  31 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  32 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+
+[[[ Keyset 'Cyclic' Tests ]]]
+
+Keyset 'Cyclic' - 8 cycles of 8 bytes - 1000000 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected        232.8, actual    129 (0.55x)
+Testing collisions (high 24-35 bits) - Worst is 35 bits: 20/29 (0.69x)
+Testing collisions (high 12-bit) - Expected    1000000.0, actual 995904 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    1000000.0, actual 999744 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected        232.8, actual    125 (0.54x)
+Testing collisions (low  24-35 bits) - Worst is 34 bits: 37/58 (0.64x)
+Testing collisions (low  12-bit) - Expected    1000000.0, actual 995904 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    1000000.0, actual 999744 (1.00x) (-256)
+Testing distribution - Worst bias is the 17-bit window at bit 22 - 0.076%
+
+Keyset 'Cyclic' - 8 cycles of 9 bytes - 1000000 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected        232.8, actual    106 (0.46x)
+Testing collisions (high 24-35 bits) - Worst is 29 bits: 948/1862 (0.51x)
+Testing collisions (high 12-bit) - Expected    1000000.0, actual 995904 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    1000000.0, actual 999744 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected        232.8, actual    121 (0.52x)
+Testing collisions (low  24-35 bits) - Worst is 32 bits: 121/232 (0.52x)
+Testing collisions (low  12-bit) - Expected    1000000.0, actual 995904 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    1000000.0, actual 999744 (1.00x) (-256)
+Testing distribution - Worst bias is the 17-bit window at bit  6 - 0.088%
+
+Keyset 'Cyclic' - 8 cycles of 10 bytes - 1000000 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected        232.8, actual    115 (0.49x)
+Testing collisions (high 24-35 bits) - Worst is 27 bits: 3685/7450 (0.49x)
+Testing collisions (high 12-bit) - Expected    1000000.0, actual 995904 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    1000000.0, actual 999744 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected        232.8, actual    121 (0.52x)
+Testing collisions (low  24-35 bits) - Worst is 35 bits: 19/29 (0.65x)
+Testing collisions (low  12-bit) - Expected    1000000.0, actual 995904 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    1000000.0, actual 999744 (1.00x) (-256)
+Testing distribution - Worst bias is the 17-bit window at bit 46 - 0.121%
+
+Keyset 'Cyclic' - 8 cycles of 11 bytes - 1000000 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected        232.8, actual    119 (0.51x)
+Testing collisions (high 24-35 bits) - Worst is 32 bits: 119/232 (0.51x)
+Testing collisions (high 12-bit) - Expected    1000000.0, actual 995904 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    1000000.0, actual 999744 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected        232.8, actual    128 (0.55x)
+Testing collisions (low  24-35 bits) - Worst is 32 bits: 128/232 (0.55x)
+Testing collisions (low  12-bit) - Expected    1000000.0, actual 995904 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    1000000.0, actual 999744 (1.00x) (-256)
+Testing distribution - Worst bias is the 17-bit window at bit 17 - 0.118%
+
+Keyset 'Cyclic' - 8 cycles of 12 bytes - 1000000 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected        232.8, actual    102 (0.44x)
+Testing collisions (high 24-35 bits) - Worst is 30 bits: 468/931 (0.50x)
+Testing collisions (high 12-bit) - Expected    1000000.0, actual 995904 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    1000000.0, actual 999744 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected        232.8, actual    134 (0.58x)
+Testing collisions (low  24-35 bits) - Worst is 34 bits: 36/58 (0.62x)
+Testing collisions (low  12-bit) - Expected    1000000.0, actual 995904 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    1000000.0, actual 999744 (1.00x) (-256)
+Testing distribution - Worst bias is the 16-bit window at bit 58 - 0.055%
+
+Keyset 'Cyclic' - 8 cycles of 16 bytes - 1000000 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected        232.8, actual    112 (0.48x)
+Testing collisions (high 24-35 bits) - Worst is 34 bits: 32/58 (0.55x)
+Testing collisions (high 12-bit) - Expected    1000000.0, actual 995904 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    1000000.0, actual 999744 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected        232.8, actual    118 (0.51x)
+Testing collisions (low  24-35 bits) - Worst is 35 bits: 18/29 (0.62x)
+Testing collisions (low  12-bit) - Expected    1000000.0, actual 995904 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    1000000.0, actual 999744 (1.00x) (-256)
+Testing distribution - Worst bias is the 17-bit window at bit 30 - 0.087%
+
+
+[[[ Keyset 'TwoBytes' Tests ]]]
+
+Keyset 'TwoBytes' - up-to-4-byte keys, 652545 total keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected         99.1, actual     45 (0.45x)
+Testing collisions (high 23-34 bits) - Worst is 29 bits: 417/793 (0.53x)
+Testing collisions (high 12-bit) - Expected     652545.0, actual 648449 (0.99x) (-4096)
+Testing collisions (high  8-bit) - Expected     652545.0, actual 652289 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected         99.1, actual     47 (0.47x)
+Testing collisions (low  23-34 bits) - Worst is 34 bits: 15/24 (0.61x)
+Testing collisions (low  12-bit) - Expected     652545.0, actual 648449 (0.99x) (-4096)
+Testing collisions (low   8-bit) - Expected     652545.0, actual 652289 (1.00x) (-256)
+Testing distribution - Worst bias is the 16-bit window at bit 24 - 0.125%
+
+Keyset 'TwoBytes' - up-to-8-byte keys, 5471025 total keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       6969.1, actual   3563 (0.51x)
+Testing collisions (high 26-40 bits) - Worst is 39 bits: 38/54 (0.70x)
+Testing collisions (high 12-bit) - Expected    5471025.0, actual 5466929 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    5471025.0, actual 5470769 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       6969.1, actual   3405 (0.49x)
+Testing collisions (low  26-40 bits) - Worst is 40 bits: 17/27 (0.62x)
+Testing collisions (low  12-bit) - Expected    5471025.0, actual 5466929 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    5471025.0, actual 5470769 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 36 - 0.047%
+
+Keyset 'TwoBytes' - up-to-12-byte keys, 18616785 total keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      80695.5, actual  40179 (0.50x)
+Testing collisions (high 28-43 bits) - Worst is 42 bits: 43/78 (0.55x)
+Testing collisions (high 12-bit) - Expected   18616785.0, actual 18612689 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected   18616785.0, actual 18616529 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      80695.5, actual  40091 (0.50x)
+Testing collisions (low  28-43 bits) - Worst is 39 bits: 352/630 (0.56x)
+Testing collisions (low  12-bit) - Expected   18616785.0, actual 18612689 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected   18616785.0, actual 18616529 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit  9 - 0.015%
+
+Keyset 'TwoBytes' - up-to-16-byte keys, 44251425 total keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected     455926.3, actual 228151 (0.50x)
+Testing collisions (high 29-46 bits) - Worst is 46 bits: 19/27 (0.68x)
+Testing collisions (high 12-bit) - Expected   44251425.0, actual 44247329 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected   44251425.0, actual 44251169 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected     455926.3, actual 227299 (0.50x)
+Testing collisions (low  29-46 bits) - Worst is 43 bits: 120/222 (0.54x)
+Testing collisions (low  12-bit) - Expected   44251425.0, actual 44247329 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected   44251425.0, actual 44251169 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit  0 - 0.011%
+
+Keyset 'TwoBytes' - up-to-20-byte keys, 86536545 total keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected    1743569.4, actual 866811 (0.50x)
+Testing collisions (high 30-48 bits) - Worst is 48 bits: 16/26 (0.60x)
+Testing collisions (high 12-bit) - Expected   86536545.0, actual 86532449 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected   86536545.0, actual 86536289 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected    1743569.4, actual 866063 (0.50x)
+Testing collisions (low  30-48 bits) - Worst is 48 bits: 16/26 (0.60x)
+Testing collisions (low  12-bit) - Expected   86536545.0, actual 86532449 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected   86536545.0, actual 86536289 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 33 - 0.003%
+
+
+[[[ Keyset 'Text' Tests ]]]
+
+Keyset 'Text' - keys of form "Foo[XXXX]Bar" - 14776336 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      50836.3, actual  25425 (0.50x)
+Testing collisions (high 28-43 bits) - Worst is 38 bits: 408/794 (0.51x)
+Testing collisions (high 12-bit) - Expected   14776336.0, actual 14772240 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected   14776336.0, actual 14776080 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      50836.3, actual  25393 (0.50x)
+Testing collisions (low  28-43 bits) - Worst is 42 bits: 29/49 (0.58x)
+Testing collisions (low  12-bit) - Expected   14776336.0, actual 14772240 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected   14776336.0, actual 14776080 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 31 - 0.016%
+
+Keyset 'Text' - keys of form "FooBar[XXXX]" - 14776336 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      50836.3, actual  25313 (0.50x)
+Testing collisions (high 28-43 bits) - Worst is 43 bits: 15/24 (0.60x)
+Testing collisions (high 12-bit) - Expected   14776336.0, actual 14772240 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected   14776336.0, actual 14776080 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      50836.3, actual  25194 (0.50x)
+Testing collisions (low  28-43 bits) - Worst is 43 bits: 14/24 (0.56x)
+Testing collisions (low  12-bit) - Expected   14776336.0, actual 14772240 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected   14776336.0, actual 14776080 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 35 - 0.030%
+
+Keyset 'Text' - keys of form "[XXXX]FooBar" - 14776336 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      50836.3, actual  25595 (0.50x)
+Testing collisions (high 28-43 bits) - Worst is 43 bits: 15/24 (0.60x)
+Testing collisions (high 12-bit) - Expected   14776336.0, actual 14772240 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected   14776336.0, actual 14776080 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      50836.3, actual  25449 (0.50x)
+Testing collisions (low  28-43 bits) - Worst is 33 bits: 12824/25418 (0.50x)
+Testing collisions (low  12-bit) - Expected   14776336.0, actual 14772240 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected   14776336.0, actual 14776080 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 50 - 0.016%
+
+
+[[[ Keyset 'Zeroes' Tests ]]]
+
+Keyset 'Zeroes' - 204800 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected          9.8, actual      7 (0.72x)
+Testing collisions (high 21-30 bits) - Worst is 30 bits: 26/39 (0.67x)
+Testing collisions (high 12-bit) - Expected     204800.0, actual 200704 (0.98x)
+Testing collisions (high  8-bit) - Expected     204800.0, actual 204544 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected          9.8, actual      5 (0.51x)
+Testing collisions (low  21-30 bits) - Worst is 24 bits: 1231/2499 (0.49x)
+Testing collisions (low  12-bit) - Expected     204800.0, actual 200704 (0.98x)
+Testing collisions (low   8-bit) - Expected     204800.0, actual 204544 (1.00x) (-256)
+Testing distribution - Worst bias is the 15-bit window at bit 14 - 0.314%
+
+
+[[[ Keyset 'Seed' Tests ]]]
+
+Keyset 'Seed' - 5000000 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       5820.8, actual   2941 (0.51x)
+Testing collisions (high 26-40 bits) - Worst is 40 bits: 13/22 (0.57x)
+Testing collisions (high 12-bit) - Expected    5000000.0, actual 4995904 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    5000000.0, actual 4999744 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       5820.8, actual   2912 (0.50x)
+Testing collisions (low  26-40 bits) - Worst is 37 bits: 105/181 (0.58x)
+Testing collisions (low  12-bit) - Expected    5000000.0, actual 4995904 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    5000000.0, actual 4999744 (1.00x) (-256)
+Testing distribution - Worst bias is the 19-bit window at bit 53 - 0.051%
+
+
+[[[ Keyset 'PerlinNoise' Tests ]]]
+
+Testing 16777216 coordinates (L2) :
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      65536.0, actual  33050 (0.50x)
+Testing collisions (high 28-43 bits) - Worst is 39 bits: 267/511 (0.52x)
+Testing collisions (high 12-bit) - Expected   16777216.0, actual 16773120 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected   16777216.0, actual 16776960 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      65536.0, actual  32690 (0.50x)
+Testing collisions (low  28-43 bits) - Worst is 42 bits: 38/63 (0.59x)
+Testing collisions (low  12-bit) - Expected   16777216.0, actual 16773120 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected   16777216.0, actual 16776960 (1.00x) (-256)
+
+
+[[[ Diff 'Differential' Tests ]]]
+
+Testing 8303632 up-to-5-bit differentials in 64-bit keys -> 64 bit hashes.
+1000 reps, 8303632000 total tests, expecting 0.00 random collisions..........
+0 total collisions, of which 0 single collisions were ignored
+
+Testing 11017632 up-to-4-bit differentials in 128-bit keys -> 64 bit hashes.
+1000 reps, 11017632000 total tests, expecting 0.00 random collisions..........
+0 total collisions, of which 0 single collisions were ignored
+
+Testing 2796416 up-to-3-bit differentials in 256-bit keys -> 64 bit hashes.
+1000 reps, 2796416000 total tests, expecting 0.00 random collisions..........
+0 total collisions, of which 0 single collisions were ignored
+
+
+[[[ DiffDist 'Differential Distribution' Tests ]]]
+
+Testing bit 0
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    503 (0.49x)
+Testing collisions (high 25-37 bits) - Worst is 33 bits: 259/511 (0.51x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    520 (0.51x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 18/31 (0.56x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 1
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    520 (0.51x)
+Testing collisions (high 25-37 bits) - Worst is 36 bits: 38/63 (0.59x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    515 (0.50x)
+Testing collisions (low  25-37 bits) - Worst is 33 bits: 261/511 (0.51x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 2
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    484 (0.47x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 18/31 (0.56x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    504 (0.49x)
+Testing collisions (low  25-37 bits) - Worst is 36 bits: 34/63 (0.53x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 3
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    504 (0.49x)
+Testing collisions (high 25-37 bits) - Worst is 35 bits: 79/127 (0.62x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    555 (0.54x)
+Testing collisions (low  25-37 bits) - Worst is 35 bits: 82/127 (0.64x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 4
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    538 (0.53x)
+Testing collisions (high 25-37 bits) - Worst is 36 bits: 37/63 (0.58x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    511 (0.50x)
+Testing collisions (low  25-37 bits) - Worst is 31 bits: 1077/2047 (0.53x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 5
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    515 (0.50x)
+Testing collisions (high 25-37 bits) - Worst is 34 bits: 139/255 (0.54x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    525 (0.51x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 18/31 (0.56x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 6
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    519 (0.51x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 19/31 (0.59x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    572 (0.56x)
+Testing collisions (low  25-37 bits) - Worst is 36 bits: 42/63 (0.66x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 7
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    535 (0.52x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 20/31 (0.63x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    518 (0.51x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 20/31 (0.63x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 8
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    561 (0.55x)
+Testing collisions (high 25-37 bits) - Worst is 32 bits: 561/1023 (0.55x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    537 (0.52x)
+Testing collisions (low  25-37 bits) - Worst is 35 bits: 68/127 (0.53x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 9
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    520 (0.51x)
+Testing collisions (high 25-37 bits) - Worst is 35 bits: 67/127 (0.52x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    505 (0.49x)
+Testing collisions (low  25-37 bits) - Worst is 30 bits: 2119/4095 (0.52x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 10
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    534 (0.52x)
+Testing collisions (high 25-37 bits) - Worst is 36 bits: 45/63 (0.70x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    489 (0.48x)
+Testing collisions (low  25-37 bits) - Worst is 28 bits: 8383/16383 (0.51x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 11
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    518 (0.51x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 18/31 (0.56x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    546 (0.53x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 18/31 (0.56x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 12
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    517 (0.50x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 20/31 (0.63x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    506 (0.49x)
+Testing collisions (low  25-37 bits) - Worst is 36 bits: 33/63 (0.52x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 13
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    549 (0.54x)
+Testing collisions (high 25-37 bits) - Worst is 36 bits: 38/63 (0.59x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    524 (0.51x)
+Testing collisions (low  25-37 bits) - Worst is 34 bits: 153/255 (0.60x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 14
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    516 (0.50x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 21/31 (0.66x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    516 (0.50x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 23/31 (0.72x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 15
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    526 (0.51x)
+Testing collisions (high 25-37 bits) - Worst is 33 bits: 267/511 (0.52x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    528 (0.52x)
+Testing collisions (low  25-37 bits) - Worst is 32 bits: 528/1023 (0.52x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 16
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    525 (0.51x)
+Testing collisions (high 25-37 bits) - Worst is 34 bits: 141/255 (0.55x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    514 (0.50x)
+Testing collisions (low  25-37 bits) - Worst is 36 bits: 40/63 (0.63x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 17
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    520 (0.51x)
+Testing collisions (high 25-37 bits) - Worst is 31 bits: 1041/2047 (0.51x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    511 (0.50x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 20/31 (0.63x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 18
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    527 (0.51x)
+Testing collisions (high 25-37 bits) - Worst is 32 bits: 527/1023 (0.51x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    573 (0.56x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 30/31 (0.94x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 19
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    502 (0.49x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 20/31 (0.63x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    489 (0.48x)
+Testing collisions (low  25-37 bits) - Worst is 34 bits: 133/255 (0.52x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 20
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    553 (0.54x)
+Testing collisions (high 25-37 bits) - Worst is 32 bits: 553/1023 (0.54x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    527 (0.51x)
+Testing collisions (low  25-37 bits) - Worst is 36 bits: 37/63 (0.58x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 21
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    499 (0.49x)
+Testing collisions (high 25-37 bits) - Worst is 36 bits: 38/63 (0.59x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    489 (0.48x)
+Testing collisions (low  25-37 bits) - Worst is 30 bits: 2085/4095 (0.51x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 22
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    507 (0.50x)
+Testing collisions (high 25-37 bits) - Worst is 34 bits: 135/255 (0.53x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    488 (0.48x)
+Testing collisions (low  25-37 bits) - Worst is 29 bits: 4118/8191 (0.50x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 23
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    501 (0.49x)
+Testing collisions (high 25-37 bits) - Worst is 36 bits: 34/63 (0.53x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    469 (0.46x)
+Testing collisions (low  25-37 bits) - Worst is 27 bits: 16619/32767 (0.51x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 24
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    519 (0.51x)
+Testing collisions (high 25-37 bits) - Worst is 31 bits: 1050/2047 (0.51x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    526 (0.51x)
+Testing collisions (low  25-37 bits) - Worst is 35 bits: 82/127 (0.64x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 25
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    532 (0.52x)
+Testing collisions (high 25-37 bits) - Worst is 36 bits: 34/63 (0.53x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    516 (0.50x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 18/31 (0.56x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 26
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    530 (0.52x)
+Testing collisions (high 25-37 bits) - Worst is 31 bits: 1063/2047 (0.52x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    525 (0.51x)
+Testing collisions (low  25-37 bits) - Worst is 29 bits: 4240/8191 (0.52x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 27
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    529 (0.52x)
+Testing collisions (high 25-37 bits) - Worst is 34 bits: 155/255 (0.61x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    496 (0.48x)
+Testing collisions (low  25-37 bits) - Worst is 35 bits: 67/127 (0.52x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 28
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    517 (0.50x)
+Testing collisions (high 25-37 bits) - Worst is 31 bits: 1049/2047 (0.51x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    523 (0.51x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 24/31 (0.75x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 29
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    522 (0.51x)
+Testing collisions (high 25-37 bits) - Worst is 36 bits: 36/63 (0.56x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    545 (0.53x)
+Testing collisions (low  25-37 bits) - Worst is 32 bits: 545/1023 (0.53x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 30
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    496 (0.48x)
+Testing collisions (high 25-37 bits) - Worst is 26 bits: 32495/65535 (0.50x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    467 (0.46x)
+Testing collisions (low  25-37 bits) - Worst is 28 bits: 8269/16383 (0.50x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 31
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    500 (0.49x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 22/31 (0.69x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    491 (0.48x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 22/31 (0.69x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 32
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    501 (0.49x)
+Testing collisions (high 25-37 bits) - Worst is 33 bits: 264/511 (0.52x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    527 (0.51x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 17/31 (0.53x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 33
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    501 (0.49x)
+Testing collisions (high 25-37 bits) - Worst is 34 bits: 142/255 (0.55x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    525 (0.51x)
+Testing collisions (low  25-37 bits) - Worst is 36 bits: 36/63 (0.56x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 34
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    488 (0.48x)
+Testing collisions (high 25-37 bits) - Worst is 30 bits: 2036/4095 (0.50x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    464 (0.45x)
+Testing collisions (low  25-37 bits) - Worst is 26 bits: 32633/65535 (0.50x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 35
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    533 (0.52x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 23/31 (0.72x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    517 (0.50x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 22/31 (0.69x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 36
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    561 (0.55x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 22/31 (0.69x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    512 (0.50x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 26/31 (0.81x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 37
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    487 (0.48x)
+Testing collisions (high 25-37 bits) - Worst is 29 bits: 4102/8191 (0.50x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    522 (0.51x)
+Testing collisions (low  25-37 bits) - Worst is 32 bits: 522/1023 (0.51x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 38
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    531 (0.52x)
+Testing collisions (high 25-37 bits) - Worst is 36 bits: 38/63 (0.59x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    471 (0.46x)
+Testing collisions (low  25-37 bits) - Worst is 34 bits: 138/255 (0.54x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 39
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    486 (0.47x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 16/31 (0.50x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    525 (0.51x)
+Testing collisions (low  25-37 bits) - Worst is 36 bits: 40/63 (0.63x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 40
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    490 (0.48x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 17/31 (0.53x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    485 (0.47x)
+Testing collisions (low  25-37 bits) - Worst is 36 bits: 40/63 (0.63x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 41
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    492 (0.48x)
+Testing collisions (high 25-37 bits) - Worst is 36 bits: 34/63 (0.53x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    539 (0.53x)
+Testing collisions (low  25-37 bits) - Worst is 36 bits: 39/63 (0.61x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 42
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    508 (0.50x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 18/31 (0.56x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    484 (0.47x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 22/31 (0.69x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 43
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    494 (0.48x)
+Testing collisions (high 25-37 bits) - Worst is 35 bits: 70/127 (0.55x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    558 (0.54x)
+Testing collisions (low  25-37 bits) - Worst is 35 bits: 76/127 (0.59x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 44
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    538 (0.53x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 21/31 (0.66x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    491 (0.48x)
+Testing collisions (low  25-37 bits) - Worst is 33 bits: 258/511 (0.50x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 45
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    543 (0.53x)
+Testing collisions (high 25-37 bits) - Worst is 32 bits: 543/1023 (0.53x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    502 (0.49x)
+Testing collisions (low  25-37 bits) - Worst is 33 bits: 264/511 (0.52x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 46
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    510 (0.50x)
+Testing collisions (high 25-37 bits) - Worst is 36 bits: 41/63 (0.64x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    488 (0.48x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 22/31 (0.69x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 47
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    528 (0.52x)
+Testing collisions (high 25-37 bits) - Worst is 34 bits: 139/255 (0.54x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    474 (0.46x)
+Testing collisions (low  25-37 bits) - Worst is 35 bits: 70/127 (0.55x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 48
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    487 (0.48x)
+Testing collisions (high 25-37 bits) - Worst is 27 bits: 16234/32767 (0.50x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    499 (0.49x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 17/31 (0.53x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 49
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    511 (0.50x)
+Testing collisions (high 25-37 bits) - Worst is 33 bits: 267/511 (0.52x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    530 (0.52x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 20/31 (0.63x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 50
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    532 (0.52x)
+Testing collisions (high 25-37 bits) - Worst is 36 bits: 38/63 (0.59x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    511 (0.50x)
+Testing collisions (low  25-37 bits) - Worst is 30 bits: 2111/4095 (0.52x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 51
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    499 (0.49x)
+Testing collisions (high 25-37 bits) - Worst is 31 bits: 1034/2047 (0.50x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    530 (0.52x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 23/31 (0.72x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 52
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    494 (0.48x)
+Testing collisions (high 25-37 bits) - Worst is 31 bits: 1029/2047 (0.50x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    461 (0.45x)
+Testing collisions (low  25-37 bits) - Worst is 36 bits: 35/63 (0.55x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 53
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    530 (0.52x)
+Testing collisions (high 25-37 bits) - Worst is 33 bits: 272/511 (0.53x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    502 (0.49x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 18/31 (0.56x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 54
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    502 (0.49x)
+Testing collisions (high 25-37 bits) - Worst is 36 bits: 36/63 (0.56x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    495 (0.48x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 22/31 (0.69x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 55
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    516 (0.50x)
+Testing collisions (high 25-37 bits) - Worst is 29 bits: 4224/8191 (0.52x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    533 (0.52x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 24/31 (0.75x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 56
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    489 (0.48x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 19/31 (0.59x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    521 (0.51x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 27/31 (0.84x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 57
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    556 (0.54x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 19/31 (0.59x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    481 (0.47x)
+Testing collisions (low  25-37 bits) - Worst is 36 bits: 42/63 (0.66x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 58
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    507 (0.50x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 18/31 (0.56x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    518 (0.51x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 18/31 (0.56x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 59
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    530 (0.52x)
+Testing collisions (high 25-37 bits) - Worst is 36 bits: 34/63 (0.53x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    450 (0.44x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 17/31 (0.53x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 60
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    494 (0.48x)
+Testing collisions (high 25-37 bits) - Worst is 30 bits: 2077/4095 (0.51x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    501 (0.49x)
+Testing collisions (low  25-37 bits) - Worst is 30 bits: 2058/4095 (0.50x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 61
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    545 (0.53x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 28/31 (0.88x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    514 (0.50x)
+Testing collisions (low  25-37 bits) - Worst is 31 bits: 1062/2047 (0.52x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 62
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    500 (0.49x)
+Testing collisions (high 25-37 bits) - Worst is 35 bits: 67/127 (0.52x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    521 (0.51x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 25/31 (0.78x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 63
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    481 (0.47x)
+Testing collisions (high 25-37 bits) - Worst is 30 bits: 2051/4095 (0.50x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    457 (0.45x)
+Testing collisions (low  25-37 bits) - Worst is 27 bits: 16460/32767 (0.50x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+
+[[[ MomentChi2 Tests ]]]
+
+Analyze hashes produced from a serie of linearly increasing numbers of 32-bit, using a step of 3 ...
+Target values to approximate : 38918200.000000 - 410450.000000
+Popcount 1 stats : 38918407.861285 - 410458.516257
+Popcount 0 stats : 38919818.441458 - 410503.734628
+MomentChi2 for bits 1 :  0.0526323
+MomentChi2 for bits 0 :   3.19062
+
+Derivative stats (transition from 2 consecutive values) :
+Popcount 1 stats : 38918414.434560 - 410444.027212
+Popcount 0 stats : 38919424.413230 - 410472.779750
+MomentChi2 for deriv b1 :  0.0560148
+MomentChi2 for deriv b0 :   1.82622
+
+  Great !!
+
+
+
+Input vcode 0x00000001, Output vcode 0x00000001, Result vcode 0x00000001
+Verification value is 0x00000001 - Testing took 978.271065 seconds
+-------------------------------------------------------------------------------
diff --git a/smhasher/clone_smhasher.sh b/smhasher/clone_smhasher.sh
new file mode 100755
index 0000000..e3290d2
--- /dev/null
+++ b/smhasher/clone_smhasher.sh
@@ -0,0 +1 @@
+git clone https://github.com/rurban/smhasher.git && cd smhasher && git apply ../0001-Add-support-for-aHash.patch
diff --git a/smhasher/fallbackOutput.txt b/smhasher/fallbackOutput.txt
new file mode 100644
index 0000000..cb324c5
--- /dev/null
+++ b/smhasher/fallbackOutput.txt
@@ -0,0 +1,1467 @@
+-------------------------------------------------------------------------------
+--- Testing ahash64 "ahash 64bit" GOOD
+
+[[[ Sanity Tests ]]]
+
+Verification value 0x52EC0BA4 ....... SKIP (self- or unseeded)
+Running sanity check 1     .......... PASS
+Running AppendedZeroesTest .......... PASS
+
+[[[ Speed Tests ]]]
+
+Bulk speed test - 262144-byte keys
+Alignment  7 -  8.506 bytes/cycle - 24336.28 MiB/sec @ 3 ghz
+Alignment  6 -  8.505 bytes/cycle - 24333.38 MiB/sec @ 3 ghz
+Alignment  5 -  8.500 bytes/cycle - 24317.30 MiB/sec @ 3 ghz
+Alignment  4 -  8.491 bytes/cycle - 24294.09 MiB/sec @ 3 ghz
+Alignment  3 -  8.491 bytes/cycle - 24293.90 MiB/sec @ 3 ghz
+Alignment  2 -  8.492 bytes/cycle - 24296.22 MiB/sec @ 3 ghz
+Alignment  1 -  8.508 bytes/cycle - 24340.25 MiB/sec @ 3 ghz
+Alignment  0 -  8.748 bytes/cycle - 25028.73 MiB/sec @ 3 ghz
+Average      -  8.530 bytes/cycle - 24405.02 MiB/sec @ 3 ghz
+
+Small key speed test -    1-byte keys -    14.97 cycles/hash
+Small key speed test -    2-byte keys -    15.00 cycles/hash
+Small key speed test -    3-byte keys -    15.00 cycles/hash
+Small key speed test -    4-byte keys -    15.00 cycles/hash
+Small key speed test -    5-byte keys -    16.00 cycles/hash
+Small key speed test -    6-byte keys -    16.00 cycles/hash
+Small key speed test -    7-byte keys -    16.11 cycles/hash
+Small key speed test -    8-byte keys -    15.00 cycles/hash
+Small key speed test -    9-byte keys -    19.04 cycles/hash
+Small key speed test -   10-byte keys -    19.70 cycles/hash
+Small key speed test -   11-byte keys -    19.43 cycles/hash
+Small key speed test -   12-byte keys -    19.54 cycles/hash
+Small key speed test -   13-byte keys -    19.65 cycles/hash
+Small key speed test -   14-byte keys -    19.45 cycles/hash
+Small key speed test -   15-byte keys -    19.00 cycles/hash
+Small key speed test -   16-byte keys -    19.45 cycles/hash
+Small key speed test -   17-byte keys -    19.84 cycles/hash
+Small key speed test -   18-byte keys -    19.65 cycles/hash
+Small key speed test -   19-byte keys -    19.36 cycles/hash
+Small key speed test -   20-byte keys -    19.74 cycles/hash
+Small key speed test -   21-byte keys -    19.56 cycles/hash
+Small key speed test -   22-byte keys -    20.11 cycles/hash
+Small key speed test -   23-byte keys -    20.08 cycles/hash
+Small key speed test -   24-byte keys -    20.29 cycles/hash
+Small key speed test -   25-byte keys -    20.55 cycles/hash
+Small key speed test -   26-byte keys -    20.42 cycles/hash
+Small key speed test -   27-byte keys -    20.43 cycles/hash
+Small key speed test -   28-byte keys -    20.37 cycles/hash
+Small key speed test -   29-byte keys -    20.42 cycles/hash
+Small key speed test -   30-byte keys -    20.42 cycles/hash
+Small key speed test -   31-byte keys -    20.37 cycles/hash
+Average                                    18.708 cycles/hash
+
+[[[ 'Hashmap' Speed Tests ]]]
+
+std::unordered_map
+Init std HashMapTest:     295.723 cycles/op (102401 inserts, 1% deletions)
+Running std HashMapTest:  124.234 cycles/op (1.7 stdv)
+
+greg7mdp/parallel-hashmap
+Init fast HashMapTest:    112.031 cycles/op (102401 inserts, 1% deletions)
+Running fast HashMapTest: 85.002 cycles/op (2.1 stdv)  ....... PASS
+
+[[[ Avalanche Tests ]]]
+
+Testing   24-bit keys ->  64-bit hashes, 300000 reps worst bias is 0.700000%
+Testing   32-bit keys ->  64-bit hashes, 300000 reps worst bias is 0.628000%
+Testing   40-bit keys ->  64-bit hashes, 300000 reps worst bias is 0.628667%
+Testing   48-bit keys ->  64-bit hashes, 300000 reps worst bias is 0.662000%
+Testing   56-bit keys ->  64-bit hashes, 300000 reps worst bias is 0.699333%
+Testing   64-bit keys ->  64-bit hashes, 300000 reps worst bias is 0.665333%
+Testing   72-bit keys ->  64-bit hashes, 300000 reps worst bias is 0.630667%
+Testing   80-bit keys ->  64-bit hashes, 300000 reps worst bias is 0.692000%
+Testing   96-bit keys ->  64-bit hashes, 300000 reps worst bias is 0.774000%
+Testing  112-bit keys ->  64-bit hashes, 300000 reps worst bias is 0.730667%
+Testing  128-bit keys ->  64-bit hashes, 300000 reps worst bias is 0.794000%
+Testing  160-bit keys ->  64-bit hashes, 300000 reps worst bias is 0.702000%
+Testing  512-bit keys ->  64-bit hashes, 300000 reps worst bias is 0.763333%
+Testing 1024-bit keys ->  64-bit hashes, 300000 reps worst bias is 0.816667%
+
+[[[ Keyset 'Sparse' Tests ]]]
+
+Keyset 'Sparse' - 16-bit keys with up to 9 bits set - 50643 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected          0.6, actual      0 (0.00x)
+Testing collisions (high 19-26 bits) - Worst is 22 bits: 320/611 (0.52x)
+Testing collisions (high 12-bit) - Expected      50643.0, actual  46547 (0.92x)
+Testing collisions (high  8-bit) - Expected      50643.0, actual  50387 (0.99x) (-256)
+Testing collisions (low  32-bit) - Expected          0.6, actual      1 (1.67x) (1)
+Testing collisions (low  19-26 bits) - Worst is 20 bits: 1168/2445 (0.48x)
+Testing collisions (low  12-bit) - Expected      50643.0, actual  46547 (0.92x)
+Testing collisions (low   8-bit) - Expected      50643.0, actual  50387 (0.99x) (-256)
+Testing distribution - Worst bias is the 13-bit window at bit  4 - 0.462%
+
+Keyset 'Sparse' - 24-bit keys with up to 8 bits set - 1271626 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected        376.5, actual    180 (0.48x)
+Testing collisions (high 24-36 bits) - Worst is 35 bits: 26/47 (0.55x)
+Testing collisions (high 12-bit) - Expected    1271626.0, actual 1267530 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    1271626.0, actual 1271370 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected        376.5, actual    184 (0.49x)
+Testing collisions (low  24-36 bits) - Worst is 34 bits: 52/94 (0.55x)
+Testing collisions (low  12-bit) - Expected    1271626.0, actual 1267530 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    1271626.0, actual 1271370 (1.00x) (-256)
+Testing distribution - Worst bias is the 17-bit window at bit  8 - 0.085%
+
+Keyset 'Sparse' - 32-bit keys with up to 7 bits set - 4514873 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       4746.0, actual   2412 (0.51x)
+Testing collisions (high 26-39 bits) - Worst is 39 bits: 24/37 (0.65x)
+Testing collisions (high 12-bit) - Expected    4514873.0, actual 4510777 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    4514873.0, actual 4514617 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       4746.0, actual   2445 (0.52x)
+Testing collisions (low  26-39 bits) - Worst is 34 bits: 630/1186 (0.53x)
+Testing collisions (low  12-bit) - Expected    4514873.0, actual 4510777 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    4514873.0, actual 4514617 (1.00x) (-256)
+Testing distribution - Worst bias is the 19-bit window at bit 47 - 0.045%
+
+Keyset 'Sparse' - 40-bit keys with up to 6 bits set - 4598479 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       4923.4, actual   2402 (0.49x)
+Testing collisions (high 26-39 bits) - Worst is 34 bits: 639/1230 (0.52x)
+Testing collisions (high 12-bit) - Expected    4598479.0, actual 4594383 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    4598479.0, actual 4598223 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       4923.4, actual   2444 (0.50x)
+Testing collisions (low  26-39 bits) - Worst is 39 bits: 22/38 (0.57x)
+Testing collisions (low  12-bit) - Expected    4598479.0, actual 4594383 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    4598479.0, actual 4598223 (1.00x) (-256)
+Testing distribution - Worst bias is the 19-bit window at bit 62 - 0.044%
+
+Keyset 'Sparse' - 48-bit keys with up to 6 bits set - 14196869 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      46927.3, actual  23533 (0.50x)
+Testing collisions (high 28-43 bits) - Worst is 43 bits: 19/22 (0.83x)
+Testing collisions (high 12-bit) - Expected   14196869.0, actual 14192773 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected   14196869.0, actual 14196613 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      46927.3, actual  23338 (0.50x)
+Testing collisions (low  28-43 bits) - Worst is 35 bits: 2947/5865 (0.50x)
+Testing collisions (low  12-bit) - Expected   14196869.0, actual 14192773 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected   14196869.0, actual 14196613 (1.00x) (-256)
+Testing distribution - Worst bias is the 19-bit window at bit 45 - 0.021%
+
+Keyset 'Sparse' - 56-bit keys with up to 5 bits set - 4216423 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       4139.3, actual   2065 (0.50x)
+Testing collisions (high 26-39 bits) - Worst is 39 bits: 22/32 (0.68x)
+Testing collisions (high 12-bit) - Expected    4216423.0, actual 4212327 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    4216423.0, actual 4216167 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       4139.3, actual   1999 (0.48x)
+Testing collisions (low  26-39 bits) - Worst is 31 bits: 4110/8278 (0.50x)
+Testing collisions (low  12-bit) - Expected    4216423.0, actual 4212327 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    4216423.0, actual 4216167 (1.00x) (-256)
+Testing distribution - Worst bias is the 19-bit window at bit 26 - 0.049%
+
+Keyset 'Sparse' - 64-bit keys with up to 5 bits set - 8303633 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      16053.7, actual   7972 (0.50x)
+Testing collisions (high 27-41 bits) - Worst is 40 bits: 39/62 (0.62x)
+Testing collisions (high 12-bit) - Expected    8303633.0, actual 8299537 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    8303633.0, actual 8303377 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      16053.7, actual   7866 (0.49x)
+Testing collisions (low  27-41 bits) - Worst is 40 bits: 36/62 (0.57x)
+Testing collisions (low  12-bit) - Expected    8303633.0, actual 8299537 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    8303633.0, actual 8303377 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 61 - 0.047%
+
+Keyset 'Sparse' - 72-bit keys with up to 5 bits set - 15082603 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      52965.5, actual  26424 (0.50x)
+Testing collisions (high 28-43 bits) - Worst is 42 bits: 32/51 (0.62x)
+Testing collisions (high 12-bit) - Expected   15082603.0, actual 15078507 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected   15082603.0, actual 15082347 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      52965.5, actual  26433 (0.50x)
+Testing collisions (low  28-43 bits) - Worst is 42 bits: 34/51 (0.66x)
+Testing collisions (low  12-bit) - Expected   15082603.0, actual 15078507 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected   15082603.0, actual 15082347 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 59 - 0.022%
+
+Keyset 'Sparse' - 96-bit keys with up to 4 bits set - 3469497 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       2802.7, actual   1406 (0.50x)
+Testing collisions (high 26-39 bits) - Worst is 33 bits: 706/1401 (0.50x)
+Testing collisions (high 12-bit) - Expected    3469497.0, actual 3465401 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    3469497.0, actual 3469241 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       2802.7, actual   1374 (0.49x)
+Testing collisions (low  26-39 bits) - Worst is 37 bits: 44/87 (0.50x)
+Testing collisions (low  12-bit) - Expected    3469497.0, actual 3465401 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    3469497.0, actual 3469241 (1.00x) (-256)
+Testing distribution - Worst bias is the 19-bit window at bit  5 - 0.066%
+
+Keyset 'Sparse' - 160-bit keys with up to 4 bits set - 26977161 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected     169446.5, actual  84730 (0.50x)
+Testing collisions (high 29-45 bits) - Worst is 45 bits: 14/20 (0.68x)
+Testing collisions (high 12-bit) - Expected   26977161.0, actual 26973065 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected   26977161.0, actual 26976905 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected     169446.5, actual  84408 (0.50x)
+Testing collisions (low  29-45 bits) - Worst is 36 bits: 5329/10590 (0.50x)
+Testing collisions (low  12-bit) - Expected   26977161.0, actual 26973065 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected   26977161.0, actual 26976905 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 20 - 0.010%
+
+Keyset 'Sparse' - 256-bit keys with up to 3 bits set - 2796417 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1820.7, actual    908 (0.50x)
+Testing collisions (high 25-38 bits) - Worst is 35 bits: 118/227 (0.52x)
+Testing collisions (high 12-bit) - Expected    2796417.0, actual 2792321 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2796417.0, actual 2796161 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1820.7, actual    921 (0.51x)
+Testing collisions (low  25-38 bits) - Worst is 38 bits: 18/28 (0.63x)
+Testing collisions (low  12-bit) - Expected    2796417.0, actual 2792321 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2796417.0, actual 2796161 (1.00x) (-256)
+Testing distribution - Worst bias is the 19-bit window at bit  8 - 0.067%
+
+Keyset 'Sparse' - 512-bit keys with up to 3 bits set - 22370049 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected     116512.9, actual  58015 (0.50x)
+Testing collisions (high 28-44 bits) - Worst is 44 bits: 19/28 (0.67x)
+Testing collisions (high 12-bit) - Expected   22370049.0, actual 22365953 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected   22370049.0, actual 22369793 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected     116512.9, actual  58134 (0.50x)
+Testing collisions (low  28-44 bits) - Worst is 40 bits: 241/455 (0.53x)
+Testing collisions (low  12-bit) - Expected   22370049.0, actual 22365953 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected   22370049.0, actual 22369793 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 62 - 0.016%
+
+Keyset 'Sparse' - 1024-bit keys with up to 2 bits set - 524801 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected         64.1, actual     30 (0.47x)
+Testing collisions (high 23-33 bits) - Worst is 33 bits: 21/32 (0.65x)
+Testing collisions (high 12-bit) - Expected     524801.0, actual 520705 (0.99x) (-4096)
+Testing collisions (high  8-bit) - Expected     524801.0, actual 524545 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected         64.1, actual     37 (0.58x)
+Testing collisions (low  23-33 bits) - Worst is 33 bits: 23/32 (0.72x)
+Testing collisions (low  12-bit) - Expected     524801.0, actual 520705 (0.99x) (-4096)
+Testing collisions (low   8-bit) - Expected     524801.0, actual 524545 (1.00x) (-256)
+Testing distribution - Worst bias is the 16-bit window at bit 54 - 0.182%
+
+Keyset 'Sparse' - 2048-bit keys with up to 2 bits set - 2098177 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1025.0, actual    529 (0.52x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 22/32 (0.69x)
+Testing collisions (high 12-bit) - Expected    2098177.0, actual 2094081 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2098177.0, actual 2097921 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1025.0, actual    525 (0.51x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 24/32 (0.75x)
+Testing collisions (low  12-bit) - Expected    2098177.0, actual 2094081 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2098177.0, actual 2097921 (1.00x) (-256)
+Testing distribution - Worst bias is the 18-bit window at bit  4 - 0.088%
+
+
+[[[ Keyset 'Permutation' Tests ]]]
+
+Combination Lowbits Tests:
+Keyset 'Combination' - up to 7 blocks from a set of 8 - 2396744 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1337.5, actual    659 (0.49x)
+Testing collisions (high 25-38 bits) - Worst is 36 bits: 55/83 (0.66x)
+Testing collisions (high 12-bit) - Expected    2396744.0, actual 2392648 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2396744.0, actual 2396488 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1337.5, actual    692 (0.52x)
+Testing collisions (low  25-38 bits) - Worst is 38 bits: 13/20 (0.62x)
+Testing collisions (low  12-bit) - Expected    2396744.0, actual 2392648 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2396744.0, actual 2396488 (1.00x) (-256)
+Testing distribution - Worst bias is the 17-bit window at bit  8 - 0.049%
+
+
+Combination Highbits Tests
+Keyset 'Combination' - up to 7 blocks from a set of 8 - 2396744 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1337.5, actual    668 (0.50x)
+Testing collisions (high 25-38 bits) - Worst is 34 bits: 175/334 (0.52x)
+Testing collisions (high 12-bit) - Expected    2396744.0, actual 2392648 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2396744.0, actual 2396488 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1337.5, actual    675 (0.50x)
+Testing collisions (low  25-38 bits) - Worst is 36 bits: 54/83 (0.65x)
+Testing collisions (low  12-bit) - Expected    2396744.0, actual 2392648 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2396744.0, actual 2396488 (1.00x) (-256)
+Testing distribution - Worst bias is the 18-bit window at bit  5 - 0.074%
+
+
+Combination Hi-Lo Tests:
+Keyset 'Combination' - up to 6 blocks from a set of 15 - 12204240 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      34678.6, actual  17094 (0.49x)
+Testing collisions (high 27-42 bits) - Worst is 36 bits: 1095/2167 (0.51x)
+Testing collisions (high 12-bit) - Expected   12204240.0, actual 12200144 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected   12204240.0, actual 12203984 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      34678.6, actual  17320 (0.50x)
+Testing collisions (low  27-42 bits) - Worst is 40 bits: 75/135 (0.55x)
+Testing collisions (low  12-bit) - Expected   12204240.0, actual 12200144 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected   12204240.0, actual 12203984 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 12 - 0.032%
+
+
+Combination 0x8000000 Tests:
+Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      16384.0, actual   8224 (0.50x)
+Testing collisions (high 27-41 bits) - Worst is 33 bits: 4198/8191 (0.51x)
+Testing collisions (high 12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      16384.0, actual   8166 (0.50x)
+Testing collisions (low  27-41 bits) - Worst is 36 bits: 529/1023 (0.52x)
+Testing collisions (low  12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 26 - 0.040%
+
+
+Combination 0x0000001 Tests:
+Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      16384.0, actual   8221 (0.50x)
+Testing collisions (high 27-41 bits) - Worst is 38 bits: 139/255 (0.54x)
+Testing collisions (high 12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      16384.0, actual   8070 (0.49x)
+Testing collisions (low  27-41 bits) - Worst is 37 bits: 273/511 (0.53x)
+Testing collisions (low  12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 33 - 0.045%
+
+
+Combination 0x800000000000000 Tests:
+Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      16384.0, actual   8143 (0.50x)
+Testing collisions (high 27-41 bits) - Worst is 41 bits: 20/31 (0.63x)
+Testing collisions (high 12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      16384.0, actual   8230 (0.50x)
+Testing collisions (low  27-41 bits) - Worst is 38 bits: 144/255 (0.56x)
+Testing collisions (low  12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 54 - 0.035%
+
+
+Combination 0x000000000000001 Tests:
+Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      16384.0, actual   8039 (0.49x)
+Testing collisions (high 27-41 bits) - Worst is 41 bits: 17/31 (0.53x)
+Testing collisions (high 12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      16384.0, actual   8271 (0.50x)
+Testing collisions (low  27-41 bits) - Worst is 41 bits: 20/31 (0.63x)
+Testing collisions (low  12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 40 - 0.045%
+
+
+Combination 16-bytes [0-1] Tests:
+Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      16384.0, actual   8194 (0.50x)
+Testing collisions (high 27-41 bits) - Worst is 33 bits: 4138/8191 (0.51x)
+Testing collisions (high 12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      16384.0, actual   8163 (0.50x)
+Testing collisions (low  27-41 bits) - Worst is 41 bits: 20/31 (0.63x)
+Testing collisions (low  12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit  9 - 0.037%
+
+
+Combination 16-bytes [0-last] Tests:
+Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      16384.0, actual   8063 (0.49x)
+Testing collisions (high 27-41 bits) - Worst is 41 bits: 18/31 (0.56x)
+Testing collisions (high 12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      16384.0, actual   8241 (0.50x)
+Testing collisions (low  27-41 bits) - Worst is 39 bits: 91/127 (0.71x)
+Testing collisions (low  12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 18 - 0.035%
+
+
+Combination 32-bytes [0-1] Tests:
+Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      16384.0, actual   7942 (0.48x)
+Testing collisions (high 27-41 bits) - Worst is 41 bits: 17/31 (0.53x)
+Testing collisions (high 12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      16384.0, actual   8191 (0.50x)
+Testing collisions (low  27-41 bits) - Worst is 41 bits: 17/31 (0.53x)
+Testing collisions (low  12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit  5 - 0.038%
+
+
+Combination 32-bytes [0-last] Tests:
+Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      16384.0, actual   8218 (0.50x)
+Testing collisions (high 27-41 bits) - Worst is 39 bits: 71/127 (0.55x)
+Testing collisions (high 12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      16384.0, actual   8144 (0.50x)
+Testing collisions (low  27-41 bits) - Worst is 30 bits: 32683/65535 (0.50x)
+Testing collisions (low  12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 42 - 0.039%
+
+
+Combination 64-bytes [0-1] Tests:
+Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      16384.0, actual   8140 (0.50x)
+Testing collisions (high 27-41 bits) - Worst is 40 bits: 39/63 (0.61x)
+Testing collisions (high 12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      16384.0, actual   8127 (0.50x)
+Testing collisions (low  27-41 bits) - Worst is 40 bits: 34/63 (0.53x)
+Testing collisions (low  12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 53 - 0.042%
+
+
+Combination 64-bytes [0-last] Tests:
+Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      16384.0, actual   8178 (0.50x)
+Testing collisions (high 27-41 bits) - Worst is 40 bits: 46/63 (0.72x)
+Testing collisions (high 12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      16384.0, actual   8354 (0.51x)
+Testing collisions (low  27-41 bits) - Worst is 38 bits: 136/255 (0.53x)
+Testing collisions (low  12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 26 - 0.038%
+
+
+Combination 128-bytes [0-1] Tests:
+Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      16384.0, actual   8384 (0.51x)
+Testing collisions (high 27-41 bits) - Worst is 32 bits: 8384/16383 (0.51x)
+Testing collisions (high 12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      16384.0, actual   8287 (0.51x)
+Testing collisions (low  27-41 bits) - Worst is 33 bits: 4188/8191 (0.51x)
+Testing collisions (low  12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 23 - 0.037%
+
+
+Combination 128-bytes [0-last] Tests:
+Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      16384.0, actual   8104 (0.49x)
+Testing collisions (high 27-41 bits) - Worst is 34 bits: 2045/4095 (0.50x)
+Testing collisions (high 12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      16384.0, actual   8263 (0.50x)
+Testing collisions (low  27-41 bits) - Worst is 41 bits: 19/31 (0.59x)
+Testing collisions (low  12-bit) - Expected    8388606.0, actual 8384510 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    8388606.0, actual 8388350 (1.00x) (-256)
+Testing distribution - Worst bias is the 19-bit window at bit 16 - 0.040%
+
+
+[[[ Keyset 'Window' Tests ]]]
+
+Keyset 'Window' -  32-bit key,  25-bit window - 32 tests, 33554432 keys per test
+Window at   0 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at   1 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at   2 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at   3 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at   4 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at   5 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at   6 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at   7 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at   8 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at   9 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  10 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  11 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  12 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  13 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  14 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  15 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  16 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  17 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  18 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  19 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  20 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  21 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  22 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  23 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  24 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  25 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  26 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  27 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  28 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  29 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  30 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  31 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Window at  32 - Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+
+[[[ Keyset 'Cyclic' Tests ]]]
+
+Keyset 'Cyclic' - 8 cycles of 8 bytes - 1000000 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected        232.8, actual    107 (0.46x)
+Testing collisions (high 24-35 bits) - Worst is 34 bits: 38/58 (0.65x)
+Testing collisions (high 12-bit) - Expected    1000000.0, actual 995904 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    1000000.0, actual 999744 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected        232.8, actual    100 (0.43x)
+Testing collisions (low  24-35 bits) - Worst is 27 bits: 3707/7450 (0.50x)
+Testing collisions (low  12-bit) - Expected    1000000.0, actual 995904 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    1000000.0, actual 999744 (1.00x) (-256)
+Testing distribution - Worst bias is the 17-bit window at bit 63 - 0.088%
+
+Keyset 'Cyclic' - 8 cycles of 9 bytes - 1000000 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected        232.8, actual    106 (0.46x)
+Testing collisions (high 24-35 bits) - Worst is 26 bits: 7405/14901 (0.50x)
+Testing collisions (high 12-bit) - Expected    1000000.0, actual 995904 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    1000000.0, actual 999744 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected        232.8, actual    126 (0.54x)
+Testing collisions (low  24-35 bits) - Worst is 35 bits: 18/29 (0.62x)
+Testing collisions (low  12-bit) - Expected    1000000.0, actual 995904 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    1000000.0, actual 999744 (1.00x) (-256)
+Testing distribution - Worst bias is the 17-bit window at bit 55 - 0.099%
+
+Keyset 'Cyclic' - 8 cycles of 10 bytes - 1000000 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected        232.8, actual    127 (0.55x)
+Testing collisions (high 24-35 bits) - Worst is 33 bits: 66/116 (0.57x)
+Testing collisions (high 12-bit) - Expected    1000000.0, actual 995904 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    1000000.0, actual 999744 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected        232.8, actual    104 (0.45x)
+Testing collisions (low  24-35 bits) - Worst is 27 bits: 3807/7450 (0.51x)
+Testing collisions (low  12-bit) - Expected    1000000.0, actual 995904 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    1000000.0, actual 999744 (1.00x) (-256)
+Testing distribution - Worst bias is the 17-bit window at bit  7 - 0.136%
+
+Keyset 'Cyclic' - 8 cycles of 11 bytes - 1000000 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected        232.8, actual    118 (0.51x)
+Testing collisions (high 24-35 bits) - Worst is 34 bits: 33/58 (0.57x)
+Testing collisions (high 12-bit) - Expected    1000000.0, actual 995904 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    1000000.0, actual 999744 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected        232.8, actual    128 (0.55x)
+Testing collisions (low  24-35 bits) - Worst is 32 bits: 128/232 (0.55x)
+Testing collisions (low  12-bit) - Expected    1000000.0, actual 995904 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    1000000.0, actual 999744 (1.00x) (-256)
+Testing distribution - Worst bias is the 17-bit window at bit 38 - 0.115%
+
+Keyset 'Cyclic' - 8 cycles of 12 bytes - 1000000 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected        232.8, actual     91 (0.39x)
+Testing collisions (high 24-35 bits) - Worst is 27 bits: 3813/7450 (0.51x)
+Testing collisions (high 12-bit) - Expected    1000000.0, actual 995904 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    1000000.0, actual 999744 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected        232.8, actual    102 (0.44x)
+Testing collisions (low  24-35 bits) - Worst is 25 bits: 14959/29802 (0.50x)
+Testing collisions (low  12-bit) - Expected    1000000.0, actual 995904 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    1000000.0, actual 999744 (1.00x) (-256)
+Testing distribution - Worst bias is the 17-bit window at bit 63 - 0.130%
+
+Keyset 'Cyclic' - 8 cycles of 16 bytes - 1000000 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected        232.8, actual    122 (0.52x)
+Testing collisions (high 24-35 bits) - Worst is 35 bits: 17/29 (0.58x)
+Testing collisions (high 12-bit) - Expected    1000000.0, actual 995904 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    1000000.0, actual 999744 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected        232.8, actual    116 (0.50x)
+Testing collisions (low  24-35 bits) - Worst is 33 bits: 61/116 (0.52x)
+Testing collisions (low  12-bit) - Expected    1000000.0, actual 995904 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    1000000.0, actual 999744 (1.00x) (-256)
+Testing distribution - Worst bias is the 17-bit window at bit 19 - 0.122%
+
+
+[[[ Keyset 'TwoBytes' Tests ]]]
+
+Keyset 'TwoBytes' - up-to-4-byte keys, 652545 total keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected         99.1, actual     47 (0.47x)
+Testing collisions (high 23-34 bits) - Worst is 34 bits: 16/24 (0.65x)
+Testing collisions (high 12-bit) - Expected     652545.0, actual 648449 (0.99x) (-4096)
+Testing collisions (high  8-bit) - Expected     652545.0, actual 652289 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected         99.1, actual     46 (0.46x)
+Testing collisions (low  23-34 bits) - Worst is 33 bits: 28/49 (0.56x)
+Testing collisions (low  12-bit) - Expected     652545.0, actual 648449 (0.99x) (-4096)
+Testing collisions (low   8-bit) - Expected     652545.0, actual 652289 (1.00x) (-256)
+Testing distribution - Worst bias is the 16-bit window at bit 34 - 0.138%
+
+Keyset 'TwoBytes' - up-to-8-byte keys, 5471025 total keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       6969.1, actual   3548 (0.51x)
+Testing collisions (high 26-40 bits) - Worst is 40 bits: 15/27 (0.55x)
+Testing collisions (high 12-bit) - Expected    5471025.0, actual 5466929 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    5471025.0, actual 5470769 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       6969.1, actual   3378 (0.48x)
+Testing collisions (low  26-40 bits) - Worst is 39 bits: 34/54 (0.62x)
+Testing collisions (low  12-bit) - Expected    5471025.0, actual 5466929 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    5471025.0, actual 5470769 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 12 - 0.056%
+
+Keyset 'TwoBytes' - up-to-12-byte keys, 18616785 total keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      80695.5, actual  40607 (0.50x)
+Testing collisions (high 28-43 bits) - Worst is 42 bits: 42/78 (0.53x)
+Testing collisions (high 12-bit) - Expected   18616785.0, actual 18612689 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected   18616785.0, actual 18616529 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      80695.5, actual  40085 (0.50x)
+Testing collisions (low  28-43 bits) - Worst is 36 bits: 2521/5043 (0.50x)
+Testing collisions (low  12-bit) - Expected   18616785.0, actual 18612689 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected   18616785.0, actual 18616529 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 56 - 0.012%
+
+Keyset 'TwoBytes' - up-to-16-byte keys, 44251425 total keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected     455926.3, actual 227080 (0.50x)
+Testing collisions (high 29-46 bits) - Worst is 46 bits: 15/27 (0.54x)
+Testing collisions (high 12-bit) - Expected   44251425.0, actual 44247329 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected   44251425.0, actual 44251169 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected     455926.3, actual 226684 (0.50x)
+Testing collisions (low  29-46 bits) - Worst is 33 bits: 113923/227963 (0.50x)
+Testing collisions (low  12-bit) - Expected   44251425.0, actual 44247329 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected   44251425.0, actual 44251169 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit  0 - 0.007%
+
+Keyset 'TwoBytes' - up-to-20-byte keys, 86536545 total keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected    1743569.4, actual 866241 (0.50x)
+Testing collisions (high 30-48 bits) - Worst is 36 bits: 54556/108973 (0.50x)
+Testing collisions (high 12-bit) - Expected   86536545.0, actual 86532449 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected   86536545.0, actual 86536289 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected    1743569.4, actual 865870 (0.50x)
+Testing collisions (low  30-48 bits) - Worst is 37 bits: 27421/54486 (0.50x)
+Testing collisions (low  12-bit) - Expected   86536545.0, actual 86532449 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected   86536545.0, actual 86536289 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit  5 - 0.005%
+
+
+[[[ Keyset 'Text' Tests ]]]
+
+Keyset 'Text' - keys of form "Foo[XXXX]Bar" - 14776336 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      50836.3, actual  25649 (0.50x)
+Testing collisions (high 28-43 bits) - Worst is 34 bits: 6513/12709 (0.51x)
+Testing collisions (high 12-bit) - Expected   14776336.0, actual 14772240 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected   14776336.0, actual 14776080 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      50836.3, actual  25314 (0.50x)
+Testing collisions (low  28-43 bits) - Worst is 40 bits: 108/198 (0.54x)
+Testing collisions (low  12-bit) - Expected   14776336.0, actual 14772240 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected   14776336.0, actual 14776080 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 35 - 0.020%
+
+Keyset 'Text' - keys of form "FooBar[XXXX]" - 14776336 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      50836.3, actual  25522 (0.50x)
+Testing collisions (high 28-43 bits) - Worst is 43 bits: 15/24 (0.60x)
+Testing collisions (high 12-bit) - Expected   14776336.0, actual 14772240 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected   14776336.0, actual 14776080 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      50836.3, actual  25294 (0.50x)
+Testing collisions (low  28-43 bits) - Worst is 41 bits: 61/99 (0.61x)
+Testing collisions (low  12-bit) - Expected   14776336.0, actual 14772240 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected   14776336.0, actual 14776080 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit 37 - 0.017%
+
+Keyset 'Text' - keys of form "[XXXX]FooBar" - 14776336 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      50836.3, actual  25439 (0.50x)
+Testing collisions (high 28-43 bits) - Worst is 38 bits: 416/794 (0.52x)
+Testing collisions (high 12-bit) - Expected   14776336.0, actual 14772240 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected   14776336.0, actual 14776080 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      50836.3, actual  25310 (0.50x)
+Testing collisions (low  28-43 bits) - Worst is 42 bits: 32/49 (0.64x)
+Testing collisions (low  12-bit) - Expected   14776336.0, actual 14772240 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected   14776336.0, actual 14776080 (1.00x) (-256)
+Testing distribution - Worst bias is the 20-bit window at bit  2 - 0.025%
+
+
+[[[ Keyset 'Zeroes' Tests ]]]
+
+Keyset 'Zeroes' - 204800 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected          9.8, actual      5 (0.51x)
+Testing collisions (high 21-30 bits) - Worst is 29 bits: 41/78 (0.52x)
+Testing collisions (high 12-bit) - Expected     204800.0, actual 200704 (0.98x)
+Testing collisions (high  8-bit) - Expected     204800.0, actual 204544 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected          9.8, actual      4 (0.41x)
+Testing collisions (low  21-30 bits) - Worst is 25 bits: 643/1249 (0.51x)
+Testing collisions (low  12-bit) - Expected     204800.0, actual 200704 (0.98x)
+Testing collisions (low   8-bit) - Expected     204800.0, actual 204544 (1.00x) (-256)
+Testing distribution - Worst bias is the 15-bit window at bit 14 - 0.281%
+
+
+[[[ Keyset 'Seed' Tests ]]]
+
+Keyset 'Seed' - 5000000 keys
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       5820.8, actual   2880 (0.49x)
+Testing collisions (high 26-40 bits) - Worst is 37 bits: 105/181 (0.58x)
+Testing collisions (high 12-bit) - Expected    5000000.0, actual 4995904 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    5000000.0, actual 4999744 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       5820.8, actual   2957 (0.51x)
+Testing collisions (low  26-40 bits) - Worst is 33 bits: 1494/2910 (0.51x)
+Testing collisions (low  12-bit) - Expected    5000000.0, actual 4995904 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    5000000.0, actual 4999744 (1.00x) (-256)
+Testing distribution - Worst bias is the 19-bit window at bit 59 - 0.046%
+
+
+[[[ Keyset 'PerlinNoise' Tests ]]]
+
+Testing 16777216 coordinates (L2) :
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected      65536.0, actual  32715 (0.50x)
+Testing collisions (high 28-43 bits) - Worst is 42 bits: 46/63 (0.72x)
+Testing collisions (high 12-bit) - Expected   16777216.0, actual 16773120 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected   16777216.0, actual 16776960 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected      65536.0, actual  32752 (0.50x)
+Testing collisions (low  28-43 bits) - Worst is 41 bits: 69/127 (0.54x)
+Testing collisions (low  12-bit) - Expected   16777216.0, actual 16773120 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected   16777216.0, actual 16776960 (1.00x) (-256)
+
+
+[[[ Diff 'Differential' Tests ]]]
+
+Testing 8303632 up-to-5-bit differentials in 64-bit keys -> 64 bit hashes.
+1000 reps, 8303632000 total tests, expecting 0.00 random collisions..........
+0 total collisions, of which 0 single collisions were ignored
+
+Testing 11017632 up-to-4-bit differentials in 128-bit keys -> 64 bit hashes.
+1000 reps, 11017632000 total tests, expecting 0.00 random collisions..........
+0 total collisions, of which 0 single collisions were ignored
+
+Testing 2796416 up-to-3-bit differentials in 256-bit keys -> 64 bit hashes.
+1000 reps, 2796416000 total tests, expecting 0.00 random collisions..........
+0 total collisions, of which 0 single collisions were ignored
+
+
+[[[ DiffDist 'Differential Distribution' Tests ]]]
+
+Testing bit 0
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    516 (0.50x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 19/31 (0.59x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    470 (0.46x)
+Testing collisions (low  25-37 bits) - Worst is 28 bits: 8112/16383 (0.50x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 1
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    514 (0.50x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 24/31 (0.75x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    507 (0.50x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 19/31 (0.59x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 2
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    536 (0.52x)
+Testing collisions (high 25-37 bits) - Worst is 34 bits: 135/255 (0.53x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    479 (0.47x)
+Testing collisions (low  25-37 bits) - Worst is 29 bits: 4068/8191 (0.50x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 3
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    535 (0.52x)
+Testing collisions (high 25-37 bits) - Worst is 32 bits: 535/1023 (0.52x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    533 (0.52x)
+Testing collisions (low  25-37 bits) - Worst is 31 bits: 1106/2047 (0.54x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 4
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    519 (0.51x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 17/31 (0.53x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    513 (0.50x)
+Testing collisions (low  25-37 bits) - Worst is 33 bits: 274/511 (0.54x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 5
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    520 (0.51x)
+Testing collisions (high 25-37 bits) - Worst is 32 bits: 520/1023 (0.51x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    527 (0.51x)
+Testing collisions (low  25-37 bits) - Worst is 33 bits: 269/511 (0.53x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 6
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    519 (0.51x)
+Testing collisions (high 25-37 bits) - Worst is 36 bits: 41/63 (0.64x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    518 (0.51x)
+Testing collisions (low  25-37 bits) - Worst is 29 bits: 4236/8191 (0.52x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 7
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    463 (0.45x)
+Testing collisions (high 25-37 bits) - Worst is 28 bits: 8190/16383 (0.50x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    497 (0.49x)
+Testing collisions (low  25-37 bits) - Worst is 34 bits: 134/255 (0.52x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 8
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    513 (0.50x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 21/31 (0.66x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    470 (0.46x)
+Testing collisions (low  25-37 bits) - Worst is 36 bits: 32/63 (0.50x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 9
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    527 (0.51x)
+Testing collisions (high 25-37 bits) - Worst is 36 bits: 37/63 (0.58x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    541 (0.53x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 19/31 (0.59x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 10
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    516 (0.50x)
+Testing collisions (high 25-37 bits) - Worst is 34 bits: 142/255 (0.55x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    470 (0.46x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 19/31 (0.59x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 11
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    500 (0.49x)
+Testing collisions (high 25-37 bits) - Worst is 31 bits: 1038/2047 (0.51x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    526 (0.51x)
+Testing collisions (low  25-37 bits) - Worst is 36 bits: 34/63 (0.53x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 12
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    503 (0.49x)
+Testing collisions (high 25-37 bits) - Worst is 35 bits: 83/127 (0.65x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    479 (0.47x)
+Testing collisions (low  25-37 bits) - Worst is 35 bits: 68/127 (0.53x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 13
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    515 (0.50x)
+Testing collisions (high 25-37 bits) - Worst is 36 bits: 40/63 (0.63x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    468 (0.46x)
+Testing collisions (low  25-37 bits) - Worst is 36 bits: 33/63 (0.52x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 14
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    465 (0.45x)
+Testing collisions (high 25-37 bits) - Worst is 36 bits: 33/63 (0.52x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    549 (0.54x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 20/31 (0.63x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 15
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    523 (0.51x)
+Testing collisions (high 25-37 bits) - Worst is 36 bits: 35/63 (0.55x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    537 (0.52x)
+Testing collisions (low  25-37 bits) - Worst is 35 bits: 71/127 (0.55x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 16
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    517 (0.50x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 19/31 (0.59x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    484 (0.47x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 25/31 (0.78x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 17
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    504 (0.49x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 18/31 (0.56x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    487 (0.48x)
+Testing collisions (low  25-37 bits) - Worst is 35 bits: 68/127 (0.53x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 18
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    534 (0.52x)
+Testing collisions (high 25-37 bits) - Worst is 33 bits: 280/511 (0.55x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    519 (0.51x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 22/31 (0.69x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 19
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    571 (0.56x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 22/31 (0.69x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    493 (0.48x)
+Testing collisions (low  25-37 bits) - Worst is 36 bits: 33/63 (0.52x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 20
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    536 (0.52x)
+Testing collisions (high 25-37 bits) - Worst is 33 bits: 272/511 (0.53x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    536 (0.52x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 23/31 (0.72x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 21
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    464 (0.45x)
+Testing collisions (high 25-37 bits) - Worst is 35 bits: 67/127 (0.52x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    536 (0.52x)
+Testing collisions (low  25-37 bits) - Worst is 35 bits: 81/127 (0.63x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 22
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    508 (0.50x)
+Testing collisions (high 25-37 bits) - Worst is 34 bits: 131/255 (0.51x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    482 (0.47x)
+Testing collisions (low  25-37 bits) - Worst is 30 bits: 2054/4095 (0.50x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 23
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    492 (0.48x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 20/31 (0.63x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    493 (0.48x)
+Testing collisions (low  25-37 bits) - Worst is 28 bits: 8176/16383 (0.50x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 24
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    518 (0.51x)
+Testing collisions (high 25-37 bits) - Worst is 30 bits: 2102/4095 (0.51x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    463 (0.45x)
+Testing collisions (low  25-37 bits) - Worst is 36 bits: 33/63 (0.52x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 25
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    532 (0.52x)
+Testing collisions (high 25-37 bits) - Worst is 32 bits: 532/1023 (0.52x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    514 (0.50x)
+Testing collisions (low  25-37 bits) - Worst is 31 bits: 1032/2047 (0.50x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 26
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    479 (0.47x)
+Testing collisions (high 25-37 bits) - Worst is 36 bits: 40/63 (0.63x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    532 (0.52x)
+Testing collisions (low  25-37 bits) - Worst is 33 bits: 269/511 (0.53x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 27
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    511 (0.50x)
+Testing collisions (high 25-37 bits) - Worst is 33 bits: 272/511 (0.53x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    450 (0.44x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 18/31 (0.56x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 28
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    538 (0.53x)
+Testing collisions (high 25-37 bits) - Worst is 34 bits: 138/255 (0.54x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    520 (0.51x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 19/31 (0.59x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 29
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    525 (0.51x)
+Testing collisions (high 25-37 bits) - Worst is 32 bits: 525/1023 (0.51x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    516 (0.50x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 23/31 (0.72x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 30
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    483 (0.47x)
+Testing collisions (high 25-37 bits) - Worst is 35 bits: 66/127 (0.52x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    512 (0.50x)
+Testing collisions (low  25-37 bits) - Worst is 30 bits: 2100/4095 (0.51x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 31
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    503 (0.49x)
+Testing collisions (high 25-37 bits) - Worst is 27 bits: 16180/32767 (0.49x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    514 (0.50x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 21/31 (0.66x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 32
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    557 (0.54x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 21/31 (0.66x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    502 (0.49x)
+Testing collisions (low  25-37 bits) - Worst is 30 bits: 2087/4095 (0.51x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 33
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    494 (0.48x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 17/31 (0.53x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    481 (0.47x)
+Testing collisions (low  25-37 bits) - Worst is 36 bits: 37/63 (0.58x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 34
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    520 (0.51x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 22/31 (0.69x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    500 (0.49x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 21/31 (0.66x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 35
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    526 (0.51x)
+Testing collisions (high 25-37 bits) - Worst is 32 bits: 526/1023 (0.51x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    507 (0.50x)
+Testing collisions (low  25-37 bits) - Worst is 34 bits: 134/255 (0.52x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 36
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    530 (0.52x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 20/31 (0.63x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    503 (0.49x)
+Testing collisions (low  25-37 bits) - Worst is 31 bits: 1034/2047 (0.50x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 37
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    489 (0.48x)
+Testing collisions (high 25-37 bits) - Worst is 35 bits: 67/127 (0.52x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    482 (0.47x)
+Testing collisions (low  25-37 bits) - Worst is 36 bits: 36/63 (0.56x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 38
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    521 (0.51x)
+Testing collisions (high 25-37 bits) - Worst is 33 bits: 273/511 (0.53x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    498 (0.49x)
+Testing collisions (low  25-37 bits) - Worst is 30 bits: 2041/4095 (0.50x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 39
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    483 (0.47x)
+Testing collisions (high 25-37 bits) - Worst is 35 bits: 72/127 (0.56x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    529 (0.52x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 20/31 (0.63x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 40
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    489 (0.48x)
+Testing collisions (high 25-37 bits) - Worst is 36 bits: 33/63 (0.52x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    499 (0.49x)
+Testing collisions (low  25-37 bits) - Worst is 29 bits: 4246/8191 (0.52x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 41
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    536 (0.52x)
+Testing collisions (high 25-37 bits) - Worst is 34 bits: 137/255 (0.54x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    543 (0.53x)
+Testing collisions (low  25-37 bits) - Worst is 33 bits: 281/511 (0.55x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 42
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    513 (0.50x)
+Testing collisions (high 25-37 bits) - Worst is 31 bits: 1082/2047 (0.53x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    494 (0.48x)
+Testing collisions (low  25-37 bits) - Worst is 34 bits: 131/255 (0.51x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 43
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    495 (0.48x)
+Testing collisions (high 25-37 bits) - Worst is 29 bits: 4158/8191 (0.51x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    473 (0.46x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 16/31 (0.50x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 44
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    479 (0.47x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 19/31 (0.59x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    541 (0.53x)
+Testing collisions (low  25-37 bits) - Worst is 35 bits: 74/127 (0.58x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 45
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    531 (0.52x)
+Testing collisions (high 25-37 bits) - Worst is 32 bits: 531/1023 (0.52x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    513 (0.50x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 18/31 (0.56x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 46
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    531 (0.52x)
+Testing collisions (high 25-37 bits) - Worst is 36 bits: 37/63 (0.58x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    510 (0.50x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 17/31 (0.53x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 47
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    502 (0.49x)
+Testing collisions (high 25-37 bits) - Worst is 28 bits: 8325/16383 (0.51x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    529 (0.52x)
+Testing collisions (low  25-37 bits) - Worst is 36 bits: 39/63 (0.61x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 48
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    512 (0.50x)
+Testing collisions (high 25-37 bits) - Worst is 35 bits: 69/127 (0.54x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    495 (0.48x)
+Testing collisions (low  25-37 bits) - Worst is 36 bits: 33/63 (0.52x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 49
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    551 (0.54x)
+Testing collisions (high 25-37 bits) - Worst is 36 bits: 38/63 (0.59x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    470 (0.46x)
+Testing collisions (low  25-37 bits) - Worst is 36 bits: 37/63 (0.58x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 50
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    483 (0.47x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 22/31 (0.69x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    512 (0.50x)
+Testing collisions (low  25-37 bits) - Worst is 31 bits: 1030/2047 (0.50x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 51
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    520 (0.51x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 17/31 (0.53x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    510 (0.50x)
+Testing collisions (low  25-37 bits) - Worst is 31 bits: 1040/2047 (0.51x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 52
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    531 (0.52x)
+Testing collisions (high 25-37 bits) - Worst is 32 bits: 531/1023 (0.52x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    534 (0.52x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 22/31 (0.69x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 53
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    546 (0.53x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 26/31 (0.81x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    483 (0.47x)
+Testing collisions (low  25-37 bits) - Worst is 35 bits: 65/127 (0.51x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 54
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    488 (0.48x)
+Testing collisions (high 25-37 bits) - Worst is 29 bits: 4102/8191 (0.50x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    501 (0.49x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 21/31 (0.66x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 55
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    509 (0.50x)
+Testing collisions (high 25-37 bits) - Worst is 34 bits: 130/255 (0.51x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    493 (0.48x)
+Testing collisions (low  25-37 bits) - Worst is 34 bits: 136/255 (0.53x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 56
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    528 (0.52x)
+Testing collisions (high 25-37 bits) - Worst is 33 bits: 274/511 (0.54x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    551 (0.54x)
+Testing collisions (low  25-37 bits) - Worst is 32 bits: 551/1023 (0.54x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 57
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    556 (0.54x)
+Testing collisions (high 25-37 bits) - Worst is 34 bits: 157/255 (0.61x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    489 (0.48x)
+Testing collisions (low  25-37 bits) - Worst is 30 bits: 2047/4095 (0.50x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 58
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    467 (0.46x)
+Testing collisions (high 25-37 bits) - Worst is 37 bits: 18/31 (0.56x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    523 (0.51x)
+Testing collisions (low  25-37 bits) - Worst is 36 bits: 39/63 (0.61x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 59
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    497 (0.49x)
+Testing collisions (high 25-37 bits) - Worst is 30 bits: 2031/4095 (0.50x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    530 (0.52x)
+Testing collisions (low  25-37 bits) - Worst is 33 bits: 278/511 (0.54x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 60
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    510 (0.50x)
+Testing collisions (high 25-37 bits) - Worst is 28 bits: 8176/16383 (0.50x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    517 (0.50x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 19/31 (0.59x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 61
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    496 (0.48x)
+Testing collisions (high 25-37 bits) - Worst is 30 bits: 2041/4095 (0.50x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    529 (0.52x)
+Testing collisions (low  25-37 bits) - Worst is 32 bits: 529/1023 (0.52x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 62
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    552 (0.54x)
+Testing collisions (high 25-37 bits) - Worst is 32 bits: 552/1023 (0.54x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    507 (0.50x)
+Testing collisions (low  25-37 bits) - Worst is 37 bits: 18/31 (0.56x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+Testing bit 63
+Testing collisions ( 64-bit) - Expected    0.0, actual      0 (0.00x)
+Testing collisions (high 32-bit) - Expected       1024.0, actual    484 (0.47x)
+Testing collisions (high 25-37 bits) - Worst is 34 bits: 135/255 (0.53x)
+Testing collisions (high 12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (high  8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+Testing collisions (low  32-bit) - Expected       1024.0, actual    500 (0.49x)
+Testing collisions (low  25-37 bits) - Worst is 33 bits: 277/511 (0.54x)
+Testing collisions (low  12-bit) - Expected    2097152.0, actual 2093056 (1.00x) (-4096)
+Testing collisions (low   8-bit) - Expected    2097152.0, actual 2096896 (1.00x) (-256)
+
+
+[[[ MomentChi2 Tests ]]]
+
+Analyze hashes produced from a serie of linearly increasing numbers of 32-bit, using a step of 3 ...
+Target values to approximate : 38918200.000000 - 410450.000000
+Popcount 1 stats : 38918484.206651 - 410464.360454
+Popcount 0 stats : 38919365.145760 - 410461.861348
+MomentChi2 for bits 1 :  0.0983945
+MomentChi2 for bits 0 :   1.65373
+
+Derivative stats (transition from 2 consecutive values) :
+Popcount 1 stats : 38917342.700616 - 410405.257542
+Popcount 0 stats : 38919729.298852 - 410467.929221
+MomentChi2 for deriv b1 :  0.895362
+MomentChi2 for deriv b0 :   2.84895
+
+  Great !!
+
+
+
+Input vcode 0x00000001, Output vcode 0x00000001, Result vcode 0x00000001
+Verification value is 0x00000001 - Testing took 934.304636 seconds
+-------------------------------------------------------------------------------
diff --git a/src/aes_hash.rs b/src/aes_hash.rs
new file mode 100644
index 0000000..54f8b6d
--- /dev/null
+++ b/src/aes_hash.rs
@@ -0,0 +1,295 @@
+use crate::convert::*;
+use crate::operations::*;
+#[cfg(feature = "specialize")]
+use crate::HasherExt;
+use core::hash::Hasher;
+use crate::RandomState;
+
+/// A `Hasher` for hashing an arbitrary stream of bytes.
+///
+/// Instances of [`AHasher`] represent state that is updated while hashing data.
+///
+/// Each method updates the internal state based on the new data provided. Once
+/// all of the data has been provided, the resulting hash can be obtained by calling
+/// `finish()`
+///
+/// [Clone] is also provided in case you wish to calculate hashes for two different items that
+/// start with the same data.
+///
+#[derive(Debug, Clone)]
+pub struct AHasher {
+    enc: u128,
+    sum: u128,
+    key: u128,
+}
+
+impl AHasher {
+    /// Creates a new hasher keyed to the provided keys.
+    ///
+    /// Normally hashers are created via `AHasher::default()` for fixed keys or `RandomState::new()` for randomly
+    /// generated keys and `RandomState::with_seeds(a,b)` for seeds that are set and can be reused. All of these work at
+    /// map creation time (and hence don't have any overhead on a per-item bais).
+    ///
+    /// This method directly creates the hasher instance and performs no transformation on the provided seeds. This may
+    /// be useful where a HashBuilder is not desired, such as for testing purposes.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::hash::Hasher;
+    /// use ahash::AHasher;
+    ///
+    /// let mut hasher = AHasher::new_with_keys(1234, 5678);
+    ///
+    /// hasher.write_u32(1989);
+    /// hasher.write_u8(11);
+    /// hasher.write_u8(9);
+    /// hasher.write(b"Huh?");
+    ///
+    /// println!("Hash is {:x}!", hasher.finish());
+    /// ```
+    #[inline]
+    pub fn new_with_keys(key1: u128, key2: u128) -> Self {
+        Self {
+            enc: key1,
+            sum: key2,
+            key: key1 ^ key2,
+        }
+    }
+
+    #[inline]
+    pub(crate) fn from_random_state(rand_state: &RandomState) -> Self {
+        let key1 = [rand_state.k0, rand_state.k1].convert();
+        let key2 = [rand_state.k2, rand_state.k3].convert();
+        Self {
+            enc: key1,
+            sum: key2,
+            key: key1 ^ key2,
+        }
+    }
+
+    #[inline(always)]
+    fn add_in_length(&mut self, length: u64) {
+        //This will be scrambled by the next AES round.
+        let mut enc: [u64; 2] = self.enc.convert();
+        enc[0] = enc[0].wrapping_add(length);
+        self.enc = enc.convert();
+    }
+
+    #[inline(always)]
+    fn hash_in(&mut self, new_value: u128) {
+        self.enc = aesenc(self.enc, new_value);
+        self.sum = shuffle_and_add(self.sum, new_value);
+    }
+
+    #[inline(always)]
+    fn hash_in_2(&mut self, v1: u128, v2: u128) {
+        self.enc = aesenc(self.enc, v1);
+        self.sum = shuffle_and_add(self.sum, v1);
+        self.enc = aesenc(self.enc, v2);
+        self.sum = shuffle_and_add(self.sum, v2);
+    }
+}
+
+#[cfg(feature = "specialize")]
+impl HasherExt for AHasher {
+    #[inline]
+    fn hash_u64(self, value: u64) -> u64 {
+        let mask = self.sum as u64;
+        let rot = (self.enc & 64) as u32;
+        folded_multiply(value ^ mask, crate::fallback_hash::MULTIPLE).rotate_left(rot)
+    }
+
+    #[inline]
+    fn short_finish(&self) -> u64 {
+        let combined = aesdec(self.sum, self.enc);
+        let result: [u64; 2] = aesenc(combined, combined).convert();
+        result[0]
+    }
+}
+
+/// Provides [Hasher] methods to hash all of the primitive types.
+///
+/// [Hasher]: core::hash::Hasher
+impl Hasher for AHasher {
+    #[inline]
+    fn write_u8(&mut self, i: u8) {
+        self.write_u64(i as u64);
+    }
+
+    #[inline]
+    fn write_u16(&mut self, i: u16) {
+        self.write_u64(i as u64);
+    }
+
+    #[inline]
+    fn write_u32(&mut self, i: u32) {
+        self.write_u64(i as u64);
+    }
+
+    #[inline]
+    fn write_u128(&mut self, i: u128) {
+        self.hash_in(i);
+    }
+
+    #[inline]
+    fn write_usize(&mut self, i: usize) {
+        self.write_u64(i as u64);
+    }
+
+    #[inline]
+    fn write_u64(&mut self, i: u64) {
+        self.write_u128(i as u128);
+    }
+
+    #[inline]
+    #[allow(clippy::collapsible_if)]
+    fn write(&mut self, input: &[u8]) {
+        let mut data = input;
+        let length = data.len();
+        self.add_in_length(length as u64);
+        //A 'binary search' on sizes reduces the number of comparisons.
+        if data.len() < 8 {
+            let value: [u64; 2] = if data.len() >= 2 {
+                if data.len() >= 4 {
+                    //len 4-8
+                    [data.read_u32().0 as u64, data.read_last_u32() as u64]
+                } else {
+                    //len 2-3
+                    [data.read_u16().0 as u64, data[data.len() - 1] as u64]
+                }
+            } else {
+                if data.len() > 0 {
+                    [data[0] as u64, 0]
+                } else {
+                    [0, 0]
+                }
+            };
+            self.hash_in(value.convert());
+        } else {
+            if data.len() > 32 {
+                if data.len() > 64 {
+                    let tail = data.read_last_u128x4();
+                    let mut current: [u128; 4] = [self.key; 4];
+                    current[0] = aesenc(current[0], tail[0]);
+                    current[1] = aesenc(current[1], tail[1]);
+                    current[2] = aesenc(current[2], tail[2]);
+                    current[3] = aesenc(current[3], tail[3]);
+                    let mut sum: [u128; 2] = [self.key, self.key];
+                    sum[0] = add_by_64s(sum[0].convert(), tail[0].convert()).convert();
+                    sum[1] = add_by_64s(sum[1].convert(), tail[1].convert()).convert();
+                    sum[0] = shuffle_and_add(sum[0], tail[2]);
+                    sum[1] = shuffle_and_add(sum[1], tail[3]);
+                    while data.len() > 64 {
+                        let (blocks, rest) = data.read_u128x4();
+                        current[0] = aesenc(current[0], blocks[0]);
+                        current[1] = aesenc(current[1], blocks[1]);
+                        current[2] = aesenc(current[2], blocks[2]);
+                        current[3] = aesenc(current[3], blocks[3]);
+                        sum[0] = shuffle_and_add(sum[0], blocks[0]);
+                        sum[1] = shuffle_and_add(sum[1], blocks[1]);
+                        sum[0] = shuffle_and_add(sum[0], blocks[2]);
+                        sum[1] = shuffle_and_add(sum[1], blocks[3]);
+                        data = rest;
+                    }
+                    self.hash_in_2(aesenc(current[0], current[1]), aesenc(current[2], current[3]));
+                    self.hash_in(add_by_64s(sum[0].convert(), sum[1].convert()).convert());
+                } else {
+                    //len 33-64
+                    let (head, _) = data.read_u128x2();
+                    let tail = data.read_last_u128x2();
+                    self.hash_in_2(head[0], head[1]);
+                    self.hash_in_2(tail[0], tail[1]);
+                }
+            } else {
+                if data.len() > 16 {
+                    //len 17-32
+                    self.hash_in_2(data.read_u128().0, data.read_last_u128());
+                } else {
+                    //len 9-16
+                    let value: [u64; 2] = [data.read_u64().0, data.read_last_u64()];
+                    self.hash_in(value.convert());
+                }
+            }
+        }
+    }
+    #[inline]
+    fn finish(&self) -> u64 {
+        let combined = aesdec(self.sum, self.enc);
+        let result: [u64; 2] = aesenc(aesenc(combined, self.key), combined).convert();
+        result[0]
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::convert::Convert;
+    use crate::operations::aesenc;
+    use crate::RandomState;
+    use std::hash::{BuildHasher, Hasher};
+    #[test]
+    fn test_sanity() {
+        let mut hasher = RandomState::with_seeds(1, 2, 3,4).build_hasher();
+        hasher.write_u64(0);
+        let h1 = hasher.finish();
+        hasher.write(&[1, 0, 0, 0, 0, 0, 0, 0]);
+        let h2 = hasher.finish();
+        assert_ne!(h1, h2);
+    }
+
+    #[cfg(feature = "compile-time-rng")]
+    #[test]
+    fn test_builder() {
+        use std::collections::HashMap;
+        use std::hash::BuildHasherDefault;
+
+        let mut map = HashMap::<u32, u64, BuildHasherDefault<AHasher>>::default();
+        map.insert(1, 3);
+    }
+
+    #[cfg(feature = "compile-time-rng")]
+    #[test]
+    fn test_default() {
+        let hasher_a = AHasher::default();
+        let a_enc: [u64; 2] = hasher_a.enc.convert();
+        let a_sum: [u64; 2] = hasher_a.sum.convert();
+        assert_ne!(0, a_enc[0]);
+        assert_ne!(0, a_enc[1]);
+        assert_ne!(0, a_sum[0]);
+        assert_ne!(0, a_sum[1]);
+        assert_ne!(a_enc[0], a_enc[1]);
+        assert_ne!(a_sum[0], a_sum[1]);
+        assert_ne!(a_enc[0], a_sum[0]);
+        assert_ne!(a_enc[1], a_sum[1]);
+        let hasher_b = AHasher::default();
+        let b_enc: [u64; 2] = hasher_b.enc.convert();
+        let b_sum: [u64; 2] = hasher_b.sum.convert();
+        assert_eq!(a_enc[0], b_enc[0]);
+        assert_eq!(a_enc[1], b_enc[1]);
+        assert_eq!(a_sum[0], b_sum[0]);
+        assert_eq!(a_sum[1], b_sum[1]);
+    }
+
+    #[test]
+    fn test_hash() {
+        let mut result: [u64; 2] = [0x6c62272e07bb0142, 0x62b821756295c58d];
+        let value: [u64; 2] = [1 << 32, 0xFEDCBA9876543210];
+        result = aesenc(value.convert(), result.convert()).convert();
+        result = aesenc(result.convert(), result.convert()).convert();
+        let mut result2: [u64; 2] = [0x6c62272e07bb0142, 0x62b821756295c58d];
+        let value2: [u64; 2] = [1, 0xFEDCBA9876543210];
+        result2 = aesenc(value2.convert(), result2.convert()).convert();
+        result2 = aesenc(result2.convert(), result.convert()).convert();
+        let result: [u8; 16] = result.convert();
+        let result2: [u8; 16] = result2.convert();
+        assert_ne!(hex::encode(result), hex::encode(result2));
+    }
+
+    #[test]
+    fn test_conversion() {
+        let input: &[u8] = "dddddddd".as_bytes();
+        let bytes: u64 = as_array!(input, 8).convert();
+        assert_eq!(bytes, 0x6464646464646464);
+    }
+}
diff --git a/src/convert.rs b/src/convert.rs
new file mode 100644
index 0000000..1bacb82
--- /dev/null
+++ b/src/convert.rs
@@ -0,0 +1,179 @@
+pub(crate) trait Convert<To> {
+    fn convert(self) -> To;
+}
+
+macro_rules! convert {
+    ($a:ty, $b:ty) => {
+        impl Convert<$b> for $a {
+            #[inline(always)]
+            fn convert(self) -> $b {
+                unsafe {
+                    let mut result: $b = core::mem::zeroed();
+                    core::ptr::copy_nonoverlapping(
+                        &self as *const $a as *const u8,
+                        &mut result as *mut $b as *mut u8,
+                        core::mem::size_of::<$b>(),
+                    );
+                    return result;
+                }
+            }
+        }
+        impl Convert<$a> for $b {
+            #[inline(always)]
+            fn convert(self) -> $a {
+                unsafe {
+                    let mut result: $a = core::mem::zeroed();
+                    core::ptr::copy_nonoverlapping(
+                        &self as *const $b as *const u8,
+                        &mut result as *mut $a as *mut u8,
+                        core::mem::size_of::<$a>(),
+                    );
+                    return result;
+                }
+            }
+        }
+    };
+}
+
+convert!([u128; 4], [u64; 8]);
+convert!([u128; 4], [u32; 16]);
+convert!([u128; 4], [u16; 32]);
+convert!([u128; 4], [u8; 64]);
+convert!([u128; 2], [u64; 4]);
+convert!([u128; 2], [u32; 8]);
+convert!([u128; 2], [u16; 16]);
+convert!([u128; 2], [u8; 32]);
+convert!(u128, [u64; 2]);
+convert!(u128, [u32; 4]);
+convert!(u128, [u16; 8]);
+convert!(u128, [u8; 16]);
+convert!([u64; 8], [u32; 16]);
+convert!([u64; 8], [u16; 32]);
+convert!([u64; 8], [u8; 64]);
+convert!([u64; 4], [u32; 8]);
+convert!([u64; 4], [u16; 16]);
+convert!([u64; 4], [u8; 32]);
+convert!([u64; 2], [u32; 4]);
+convert!([u64; 2], [u16; 8]);
+convert!([u64; 2], [u8; 16]);
+convert!([u32; 4], [u16; 8]);
+convert!([u32; 4], [u8; 16]);
+convert!([u16; 8], [u8; 16]);
+convert!(u64, [u32; 2]);
+convert!(u64, [u16; 4]);
+convert!(u64, [u8; 8]);
+convert!([u32; 2], [u16; 4]);
+convert!([u32; 2], [u8; 8]);
+convert!(u32, [u16; 2]);
+convert!(u32, [u8; 4]);
+convert!([u16; 2], [u8; 4]);
+convert!(u16, [u8; 2]);
+convert!([[u64; 4]; 2], [u8; 64]);
+
+convert!([f64; 2], [u8; 16]);
+convert!([f32; 4], [u8; 16]);
+convert!(f64, [u8; 8]);
+convert!([f32; 2], [u8; 8]);
+convert!(f32, [u8; 4]);
+
+macro_rules! as_array {
+    ($input:expr, $len:expr) => {{
+        {
+            #[inline(always)]
+            fn as_array<T>(slice: &[T]) -> &[T; $len] {
+                assert_eq!(slice.len(), $len);
+                unsafe { &*(slice.as_ptr() as *const [_; $len]) }
+            }
+            as_array($input)
+        }
+    }};
+}
+
+pub(crate) trait ReadFromSlice {
+    fn read_u16(&self) -> (u16, &[u8]);
+    fn read_u32(&self) -> (u32, &[u8]);
+    fn read_u64(&self) -> (u64, &[u8]);
+    fn read_u128(&self) -> (u128, &[u8]);
+    fn read_u128x2(&self) -> ([u128; 2], &[u8]);
+    fn read_u128x4(&self) -> ([u128; 4], &[u8]);
+    fn read_last_u16(&self) -> u16;
+    fn read_last_u32(&self) -> u32;
+    fn read_last_u64(&self) -> u64;
+    fn read_last_u128(&self) -> u128;
+    fn read_last_u128x2(&self) -> [u128; 2];
+    fn read_last_u128x4(&self) -> [u128; 4];
+}
+
+impl ReadFromSlice for [u8] {
+    #[inline(always)]
+    fn read_u16(&self) -> (u16, &[u8]) {
+        let (value, rest) = self.split_at(2);
+        (as_array!(value, 2).convert(), rest)
+    }
+
+    #[inline(always)]
+    fn read_u32(&self) -> (u32, &[u8]) {
+        let (value, rest) = self.split_at(4);
+        (as_array!(value, 4).convert(), rest)
+    }
+
+    #[inline(always)]
+    fn read_u64(&self) -> (u64, &[u8]) {
+        let (value, rest) = self.split_at(8);
+        (as_array!(value, 8).convert(), rest)
+    }
+
+    #[inline(always)]
+    fn read_u128(&self) -> (u128, &[u8]) {
+        let (value, rest) = self.split_at(16);
+        (as_array!(value, 16).convert(), rest)
+    }
+
+    #[inline(always)]
+    fn read_u128x2(&self) -> ([u128; 2], &[u8]) {
+        let (value, rest) = self.split_at(32);
+        (as_array!(value, 32).convert(), rest)
+    }
+
+    #[inline(always)]
+    fn read_u128x4(&self) -> ([u128; 4], &[u8]) {
+        let (value, rest) = self.split_at(64);
+        (as_array!(value, 64).convert(), rest)
+    }
+
+    #[inline(always)]
+    fn read_last_u16(&self) -> u16 {
+        let (_, value) = self.split_at(self.len() - 2);
+        as_array!(value, 2).convert()
+    }
+
+    #[inline(always)]
+    fn read_last_u32(&self) -> u32 {
+        let (_, value) = self.split_at(self.len() - 4);
+        as_array!(value, 4).convert()
+    }
+
+    #[inline(always)]
+    fn read_last_u64(&self) -> u64 {
+        let (_, value) = self.split_at(self.len() - 8);
+        as_array!(value, 8).convert()
+    }
+
+    #[inline(always)]
+    fn read_last_u128(&self) -> u128 {
+        let (_, value) = self.split_at(self.len() - 16);
+        as_array!(value, 16).convert()
+    }
+
+    #[inline(always)]
+    fn read_last_u128x2(&self) -> [u128; 2] {
+        let (_, value) = self.split_at(self.len() - 32);
+        as_array!(value, 32).convert()
+    }
+
+    #[inline(always)]
+    fn read_last_u128x4(&self) -> [u128; 4] {
+        let (_, value) = self.split_at(self.len() - 64);
+        as_array!(value, 64).convert()
+    }
+}
diff --git a/src/fallback_hash.rs b/src/fallback_hash.rs
new file mode 100644
index 0000000..3eaacf9
--- /dev/null
+++ b/src/fallback_hash.rs
@@ -0,0 +1,226 @@
+use crate::convert::*;
+use crate::operations::folded_multiply;
+#[cfg(feature = "specialize")]
+use crate::HasherExt;
+use core::hash::Hasher;
+use crate::RandomState;
+use crate::random_state::PI;
+
+///This constant come from Kunth's prng (Empirically it works better than those from splitmix32).
+pub(crate) const MULTIPLE: u64 = 6364136223846793005;
+const ROT: u32 = 23; //17
+
+/// A `Hasher` for hashing an arbitrary stream of bytes.
+///
+/// Instances of [`AHasher`] represent state that is updated while hashing data.
+///
+/// Each method updates the internal state based on the new data provided. Once
+/// all of the data has been provided, the resulting hash can be obtained by calling
+/// `finish()`
+///
+/// [Clone] is also provided in case you wish to calculate hashes for two different items that
+/// start with the same data.
+///
+#[derive(Debug, Clone)]
+pub struct AHasher {
+    buffer: u64,
+    pad: u64,
+    extra_keys: [u64; 2],
+}
+
+impl AHasher {
+    /// Creates a new hasher keyed to the provided key.
+    #[inline]
+    #[allow(dead_code)] // Is not called if non-fallback hash is used.
+    pub fn new_with_keys(key1: u128, key2: u128) -> AHasher {
+        let pi: [u128; 2] = PI.convert();
+        let key1: [u64; 2] = (key1 ^ pi[0]).convert();
+        let key2: [u64; 2] = (key2 ^ pi[1]).convert();
+        AHasher {
+            buffer: key1[0],
+            pad: key1[1],
+            extra_keys: key2,
+        }
+    }
+ 
+    #[inline]
+    #[allow(dead_code)] // Is not called if non-fallback hash is used.
+    pub(crate) fn from_random_state(rand_state: &RandomState) -> AHasher  {
+        AHasher {
+            buffer: rand_state.k0,
+            pad: rand_state.k1,
+            extra_keys: [rand_state.k2, rand_state.k3],
+        }
+    }
+
+    /// This update function has the goal of updating the buffer with a single multiply
+    /// FxHash does this but is vulnerable to attack. To avoid this input needs to be masked to with an
+    /// unpredictable value. Other hashes such as murmurhash have taken this approach but were found vulnerable
+    /// to attack. The attack was based on the idea of reversing the pre-mixing (Which is necessarily
+    /// reversible otherwise bits would be lost) then placing a difference in the highest bit before the
+    /// multiply used to mix the data. Because a multiply can never affect the bits to the right of it, a
+    /// subsequent update that also differed in this bit could result in a predictable collision.
+    ///
+    /// This version avoids this vulnerability while still only using a single multiply. It takes advantage
+    /// of the fact that when a 64 bit multiply is performed the upper 64 bits are usually computed and thrown
+    /// away. Instead it creates two 128 bit values where the upper 64 bits are zeros and multiplies them.
+    /// (The compiler is smart enough to turn this into a 64 bit multiplication in the assembly)
+    /// Then the upper bits are xored with the lower bits to produce a single 64 bit result.
+    ///
+    /// To understand why this is a good scrambling function it helps to understand multiply-with-carry PRNGs:
+    /// https://en.wikipedia.org/wiki/Multiply-with-carry_pseudorandom_number_generator
+    /// If the multiple is chosen well, this creates a long period, decent quality PRNG.
+    /// Notice that this function is equivalent to this except the `buffer`/`state` is being xored with each
+    /// new block of data. In the event that data is all zeros, it is exactly equivalent to a MWC PRNG.
+    ///
+    /// This is impervious to attack because every bit buffer at the end is dependent on every bit in
+    /// `new_data ^ buffer`. For example suppose two inputs differed in only the 5th bit. Then when the
+    /// multiplication is performed the `result` will differ in bits 5-69. More specifically it will differ by
+    /// 2^5 * MULTIPLE. However in the next step bits 65-128 are turned into a separate 64 bit value. So the
+    /// differing bits will be in the lower 6 bits of this value. The two intermediate values that differ in
+    /// bits 5-63 and in bits 0-5 respectively get added together. Producing an output that differs in every
+    /// bit. The addition carries in the multiplication and at the end additionally mean that the even if an
+    /// attacker somehow knew part of (but not all) the contents of the buffer before hand,
+    /// they would not be able to predict any of the bits in the buffer at the end.
+    #[inline(always)]
+    fn update(&mut self, new_data: u64) {
+        self.buffer = folded_multiply(new_data ^ self.buffer, MULTIPLE);
+    }
+
+    /// Similar to the above this function performs an update using a "folded multiply".
+    /// However it takes in 128 bits of data instead of 64. Both halves must be masked.
+    ///
+    /// This makes it impossible for an attacker to place a single bit difference between
+    /// two blocks so as to cancel each other.
+    ///
+    /// However this is not sufficient. to prevent (a,b) from hashing the same as (b,a) the buffer itself must
+    /// be updated between calls in a way that does not commute. To achieve this XOR and Rotate are used.
+    /// Add followed by xor is not the same as xor followed by add, and rotate ensures that the same out bits
+    /// can't be changed by the same set of input bits. To cancel this sequence with subsequent input would require
+    /// knowing the keys.
+    #[inline(always)]
+    fn large_update(&mut self, new_data: u128) {
+        let block: [u64; 2] = new_data.convert();
+        let combined = folded_multiply(block[0] ^ self.extra_keys[0], block[1] ^ self.extra_keys[1]);
+        self.buffer = (self.pad.wrapping_add(combined) ^ self.buffer).rotate_left(ROT);
+    }
+}
+
+#[cfg(feature = "specialize")]
+impl HasherExt for AHasher {
+    #[inline]
+    fn hash_u64(self, value: u64) -> u64 {
+        let rot = (self.pad & 64) as u32;
+        folded_multiply(value ^ self.buffer, MULTIPLE).rotate_left(rot)
+    }
+
+    #[inline]
+    fn short_finish(&self) -> u64 {
+        self.buffer.wrapping_add(self.pad)
+    }
+}
+
+/// Provides [Hasher] methods to hash all of the primitive types.
+///
+/// [Hasher]: core::hash::Hasher
+impl Hasher for AHasher {
+    #[inline]
+    fn write_u8(&mut self, i: u8) {
+        self.update(i as u64);
+    }
+
+    #[inline]
+    fn write_u16(&mut self, i: u16) {
+        self.update(i as u64);
+    }
+
+    #[inline]
+    fn write_u32(&mut self, i: u32) {
+        self.update(i as u64);
+    }
+
+    #[inline]
+    fn write_u64(&mut self, i: u64) {
+        self.update(i as u64);
+    }
+
+    #[inline]
+    fn write_u128(&mut self, i: u128) {
+        self.large_update(i);
+    }
+
+    #[inline]
+    fn write_usize(&mut self, i: usize) {
+        self.write_u64(i as u64);
+    }
+
+    #[inline]
+    #[allow(clippy::collapsible_if)]
+    fn write(&mut self, input: &[u8]) {
+        let mut data = input;
+        let length = data.len() as u64;
+        //Needs to be an add rather than an xor because otherwise it could be canceled with carefully formed input.
+        self.buffer = self.buffer.wrapping_add(length).wrapping_mul(MULTIPLE);
+        //A 'binary search' on sizes reduces the number of comparisons.
+        if data.len() > 8 {
+            if data.len() > 16 {
+                let tail = data.read_last_u128();
+                self.large_update(tail);
+                while data.len() > 16 {
+                    let (block, rest) = data.read_u128();
+                    self.large_update(block);
+                    data = rest;
+                }
+            } else {
+                self.large_update([data.read_u64().0, data.read_last_u64()].convert());
+            }
+        } else {
+            if data.len() >= 2 {
+                if data.len() >= 4 {
+                    let block = [data.read_u32().0 as u64, data.read_last_u32() as u64];
+                    self.large_update(block.convert());
+                } else {
+                    let value = [data.read_u16().0 as u32, data[data.len() - 1] as u32];
+                    self.update(value.convert());
+                }
+            } else {
+                if data.len() > 0 {
+                    self.update(data[0] as u64);
+                }
+            }
+        }
+    }
+    #[inline]
+    fn finish(&self) -> u64 {
+        let rot = (self.buffer & 63) as u32;
+        folded_multiply(self.buffer, self.pad).rotate_left(rot)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::convert::Convert;
+    use crate::fallback_hash::*;
+
+    #[test]
+    fn test_hash() {
+        let mut hasher = AHasher::new_with_keys(0, 0);
+        let value: u64 = 1 << 32;
+        hasher.update(value);
+        let result = hasher.buffer;
+        let mut hasher = AHasher::new_with_keys(0, 0);
+        let value2: u64 = 1;
+        hasher.update(value2);
+        let result2 = hasher.buffer;
+        let result: [u8; 8] = result.convert();
+        let result2: [u8; 8] = result2.convert();
+        assert_ne!(hex::encode(result), hex::encode(result2));
+    }
+
+    #[test]
+    fn test_conversion() {
+        let input: &[u8] = "dddddddd".as_bytes();
+        let bytes: u64 = as_array!(input, 8).convert();
+        assert_eq!(bytes, 0x6464646464646464);
+    }
+}
diff --git a/src/hash_map.rs b/src/hash_map.rs
new file mode 100644
index 0000000..53cd73c
--- /dev/null
+++ b/src/hash_map.rs
@@ -0,0 +1,329 @@
+use std::borrow::Borrow;
+use std::collections::{hash_map, HashMap};
+use std::fmt::{self, Debug};
+use std::hash::{BuildHasher, Hash};
+use std::iter::FromIterator;
+use std::ops::{Deref, DerefMut, Index};
+use std::panic::UnwindSafe;
+
+use crate::{RandomState};
+
+/// A [`HashMap`](std::collections::HashMap) using [`RandomState`](crate::RandomState) to hash the items.
+/// (Requires the `std` feature to be enabled.)
+#[derive(Clone)]
+pub struct AHashMap<K, V, S = crate::RandomState>(HashMap<K, V, S>);
+
+impl<K, V> From<HashMap<K, V, crate::RandomState>> for AHashMap<K, V> {
+    fn from(item: HashMap<K, V, crate::RandomState>) -> Self {
+        AHashMap(item)
+    }
+}
+
+impl<K, V> Into<HashMap<K, V, crate::RandomState>> for AHashMap<K, V> {
+    fn into(self) -> HashMap<K, V, crate::RandomState> {
+        self.0
+    }
+}
+
+impl<K, V> AHashMap<K, V, RandomState> {
+    pub fn new() -> Self {
+        AHashMap(HashMap::with_hasher(RandomState::default()))
+    }
+
+    pub fn with_capacity(capacity: usize) -> Self {
+        AHashMap(HashMap::with_capacity_and_hasher(capacity, RandomState::default()))
+    }
+}
+
+impl<K, V, S> AHashMap<K, V, S> where S: BuildHasher {
+
+    pub fn with_hasher(hash_builder: S) -> Self {
+        AHashMap(HashMap::with_hasher(hash_builder))
+    }
+
+    pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self {
+        AHashMap(HashMap::with_capacity_and_hasher(capacity, hash_builder))
+    }
+}
+
+impl<K, V, S> AHashMap<K, V, S>
+where
+    K: Hash + Eq,
+    S: BuildHasher
+{
+    /// Returns a reference to the value corresponding to the key.
+    ///
+    /// The key may be any borrowed form of the map's key type, but
+    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
+    /// the key type.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut map = HashMap::new();
+    /// map.insert(1, "a");
+    /// assert_eq!(map.get(&1), Some(&"a"));
+    /// assert_eq!(map.get(&2), None);
+    /// ```
+    #[inline]
+    pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
+    where
+        K: Borrow<Q>,
+        Q: Hash + Eq,
+    {
+        self.0.get(k)
+    }
+
+    /// Returns the key-value pair corresponding to the supplied key.
+    ///
+    /// The supplied key may be any borrowed form of the map's key type, but
+    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
+    /// the key type.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut map = HashMap::new();
+    /// map.insert(1, "a");
+    /// assert_eq!(map.get_key_value(&1), Some((&1, &"a")));
+    /// assert_eq!(map.get_key_value(&2), None);
+    /// ```
+    #[inline]
+    pub fn get_key_value<Q: ?Sized>(&self, k: &Q) -> Option<(&K, &V)>
+    where
+        K: Borrow<Q>,
+        Q: Hash + Eq,
+    {
+        self.0.get_key_value(k)
+    }
+
+    /// Returns a mutable reference to the value corresponding to the key.
+    ///
+    /// The key may be any borrowed form of the map's key type, but
+    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
+    /// the key type.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut map = HashMap::new();
+    /// map.insert(1, "a");
+    /// if let Some(x) = map.get_mut(&1) {
+    ///     *x = "b";
+    /// }
+    /// assert_eq!(map[&1], "b");
+    /// ```
+    #[inline]
+    pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V>
+    where
+        K: Borrow<Q>,
+        Q: Hash + Eq,
+    {
+        self.0.get_mut(k)
+    }
+
+    /// Inserts a key-value pair into the map.
+    ///
+    /// If the map did not have this key present, [`None`] is returned.
+    ///
+    /// If the map did have this key present, the value is updated, and the old
+    /// value is returned. The key is not updated, though; this matters for
+    /// types that can be `==` without being identical. See the [module-level
+    /// documentation] for more.
+    ///
+    /// [module-level documentation]: crate::collections#insert-and-complex-keys
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut map = HashMap::new();
+    /// assert_eq!(map.insert(37, "a"), None);
+    /// assert_eq!(map.is_empty(), false);
+    ///
+    /// map.insert(37, "b");
+    /// assert_eq!(map.insert(37, "c"), Some("b"));
+    /// assert_eq!(map[&37], "c");
+    /// ```
+    #[inline]
+    pub fn insert(&mut self, k: K, v: V) -> Option<V> {
+        self.0.insert(k, v)
+    }
+
+    /// Removes a key from the map, returning the value at the key if the key
+    /// was previously in the map.
+    ///
+    /// The key may be any borrowed form of the map's key type, but
+    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
+    /// the key type.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut map = HashMap::new();
+    /// map.insert(1, "a");
+    /// assert_eq!(map.remove(&1), Some("a"));
+    /// assert_eq!(map.remove(&1), None);
+    /// ```
+    #[inline]
+    pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V>
+    where
+        K: Borrow<Q>,
+        Q: Hash + Eq,
+    {
+        self.0.remove(k)
+    }
+}
+
+impl<K, V, S> Deref for AHashMap<K, V, S> {
+    type Target = HashMap<K, V, S>;
+    fn deref(&self) -> &Self::Target {
+        &self.0
+    }
+}
+
+impl<K, V, S> DerefMut for AHashMap<K, V, S> {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        &mut self.0
+    }
+}
+
+impl<K, V, S> UnwindSafe for AHashMap<K, V, S>
+where
+    K: UnwindSafe,
+    V: UnwindSafe,
+{
+}
+
+impl<K, V, S> PartialEq for AHashMap<K, V, S>
+where
+    K: Eq + Hash,
+    V: PartialEq,
+    S: BuildHasher,
+{
+    fn eq(&self, other: &AHashMap<K, V, S>) -> bool {
+        self.0.eq(&other.0)
+    }
+}
+
+impl<K, V, S> Eq for AHashMap<K, V, S>
+where
+    K: Eq + Hash,
+    V: Eq,
+    S: BuildHasher,
+{
+}
+
+impl<K, Q: ?Sized, V, S> Index<&Q> for AHashMap<K, V, S>
+where
+    K: Eq + Hash + Borrow<Q>,
+    Q: Eq + Hash,
+    S: BuildHasher,
+{
+    type Output = V;
+
+    /// Returns a reference to the value corresponding to the supplied key.
+    ///
+    /// # Panics
+    ///
+    /// Panics if the key is not present in the `HashMap`.
+    #[inline]
+    fn index(&self, key: &Q) -> &V {
+        self.0.index(key)
+    }
+}
+
+impl<K, V, S> Debug for AHashMap<K, V, S>
+where
+    K: Debug,
+    V: Debug,
+    S: BuildHasher,
+{
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        self.0.fmt(fmt)
+    }
+}
+
+impl<K, V, S> FromIterator<(K, V)> for AHashMap<K, V, S>
+where
+    K: Eq + Hash,
+    S: BuildHasher + Default,
+{
+    fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
+        AHashMap(HashMap::from_iter(iter))
+    }
+}
+
+impl<'a, K, V, S> IntoIterator for &'a AHashMap<K, V, S> {
+    type Item = (&'a K, &'a V);
+    type IntoIter = hash_map::Iter<'a, K, V>;
+    fn into_iter(self) -> Self::IntoIter {
+        (&self.0).iter()
+    }
+}
+
+impl<'a, K, V, S> IntoIterator for &'a mut AHashMap<K, V, S> {
+    type Item = (&'a K, &'a mut V);
+    type IntoIter = hash_map::IterMut<'a, K, V>;
+    fn into_iter(self) -> Self::IntoIter {
+        (&mut self.0).iter_mut()
+    }
+}
+
+impl<K, V, S> IntoIterator for AHashMap<K, V, S> {
+    type Item = (K, V);
+    type IntoIter = hash_map::IntoIter<K, V>;
+    fn into_iter(self) -> Self::IntoIter {
+        self.0.into_iter()
+    }
+}
+
+impl<K, V, S> Extend<(K, V)> for AHashMap<K, V, S>
+where
+    K: Eq + Hash,
+    S: BuildHasher,
+{
+    #[inline]
+    fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
+        self.0.extend(iter)
+    }
+}
+
+impl<'a, K, V, S> Extend<(&'a K, &'a V)> for AHashMap<K, V, S>
+where
+    K: Eq + Hash + Copy + 'a,
+    V: Copy + 'a,
+    S: BuildHasher,
+{
+    #[inline]
+    fn extend<T: IntoIterator<Item = (&'a K, &'a V)>>(&mut self, iter: T) {
+        self.0.extend(iter)
+    }
+}
+
+impl<K, V> Default for AHashMap<K, V, RandomState> {
+    #[inline]
+    fn default() -> AHashMap<K, V, RandomState> {
+        AHashMap::new()
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+    #[test]
+    fn test_borrow() {
+        let mut map: AHashMap<String, String> = AHashMap::new();
+        map.insert("foo".to_string(), "Bar".to_string());
+        map.insert("Bar".to_string(), map.get("foo").unwrap().to_owned());
+    }
+}
diff --git a/src/hash_quality_test.rs b/src/hash_quality_test.rs
new file mode 100644
index 0000000..2229803
--- /dev/null
+++ b/src/hash_quality_test.rs
@@ -0,0 +1,455 @@
+use crate::{CallHasher, HasherExt};
+use core::hash::{Hash, Hasher};
+use std::collections::HashMap;
+
+fn assert_sufficiently_different(a: u64, b: u64, tolerance: i32) {
+    let (same_byte_count, same_nibble_count) = count_same_bytes_and_nibbles(a, b);
+    assert!(same_byte_count <= tolerance, "{:x} vs {:x}: {:}", a, b, same_byte_count);
+    assert!(
+        same_nibble_count <= tolerance * 3,
+        "{:x} vs {:x}: {:}",
+        a,
+        b,
+        same_nibble_count
+    );
+    let flipped_bits = (a ^ b).count_ones();
+    assert!(
+        flipped_bits > 12 && flipped_bits < 52,
+        "{:x} and {:x}: {:}",
+        a,
+        b,
+        flipped_bits
+    );
+    for rotate in 0..64 {
+        let flipped_bits2 = (a ^ (b.rotate_left(rotate))).count_ones();
+        assert!(
+            flipped_bits2 > 10 && flipped_bits2 < 54,
+            "{:x} and {:x}: {:}",
+            a,
+            b.rotate_left(rotate),
+            flipped_bits2
+        );
+    }
+}
+
+fn count_same_bytes_and_nibbles(a: u64, b: u64) -> (i32, i32) {
+    let mut same_byte_count = 0;
+    let mut same_nibble_count = 0;
+    for byte in 0..8 {
+        let ba = (a >> (8 * byte)) as u8;
+        let bb = (b >> (8 * byte)) as u8;
+        if ba == bb {
+            same_byte_count += 1;
+        }
+        if ba & 0xF0u8 == bb & 0xF0u8 {
+            same_nibble_count += 1;
+        }
+        if ba & 0x0Fu8 == bb & 0x0Fu8 {
+            same_nibble_count += 1;
+        }
+    }
+    (same_byte_count, same_nibble_count)
+}
+
+fn gen_combinations(options: &[u32; 8], depth: u32, so_far: Vec<u32>, combinations: &mut Vec<Vec<u32>>) {
+    if depth == 0 {
+        return;
+    }
+    for option in options {
+        let mut next = so_far.clone();
+        next.push(*option);
+        combinations.push(next.clone());
+        gen_combinations(options, depth - 1, next, combinations);
+    }
+}
+
+fn test_no_full_collisions<T: Hasher>(gen_hash: impl Fn() -> T) {
+    let options: [u32; 8] = [
+        0x00000000, 0x20000000, 0x40000000, 0x60000000, 0x80000000, 0xA0000000, 0xC0000000, 0xE0000000,
+    ];
+    let mut combinations = Vec::new();
+    gen_combinations(&options, 7, Vec::new(), &mut combinations);
+    let mut map: HashMap<u64, Vec<u8>> = HashMap::new();
+    for combination in combinations {
+        let array = unsafe {
+            let (begin, middle, end) = combination.align_to::<u8>();
+            assert_eq!(0, begin.len());
+            assert_eq!(0, end.len());
+            middle.to_vec()
+        };
+        let mut hasher = gen_hash();
+        hasher.write(&array);
+        let hash = hasher.finish();
+        if let Some(value) = map.get(&hash) {
+            assert_eq!(
+                value, &array,
+                "Found a collision between {:x?} and {:x?}",
+                value, &array
+            );
+        } else {
+            map.insert(hash, array);
+        }
+    }
+    assert_eq!(2396744, map.len());
+}
+
+fn test_keys_change_output<T: HasherExt>(constructor: impl Fn(u128, u128) -> T) {
+    let mut a = constructor(1, 1);
+    let mut b = constructor(1, 2);
+    let mut c = constructor(2, 1);
+    let mut d = constructor(2, 2);
+    "test".hash(&mut a);
+    "test".hash(&mut b);
+    "test".hash(&mut c);
+    "test".hash(&mut d);
+    assert_sufficiently_different(a.finish(), b.finish(), 1);
+    assert_sufficiently_different(a.finish(), c.finish(), 1);
+    assert_sufficiently_different(a.finish(), d.finish(), 1);
+    assert_sufficiently_different(b.finish(), c.finish(), 1);
+    assert_sufficiently_different(b.finish(), d.finish(), 1);
+    assert_sufficiently_different(c.finish(), d.finish(), 1);
+}
+
+fn test_input_affect_every_byte<T: HasherExt>(constructor: impl Fn(u128, u128) -> T) {
+    let base = 0.get_hash(constructor(0, 0));
+    for shift in 0..16 {
+        let mut alternitives = vec![];
+        for v in 0..256 {
+            let input = (v as u128) << (shift * 8);
+            let hasher = constructor(0, 0);
+            alternitives.push(input.get_hash(hasher));
+        }
+        assert_each_byte_differs(base, alternitives);
+    }
+}
+
+///Ensures that for every bit in the output there is some value for each byte in the key that flips it.
+fn test_keys_affect_every_byte<H: Hash, T: HasherExt>(item: H, constructor: impl Fn(u128, u128) -> T) {
+    let base = item.get_hash(constructor(0, 0));
+    for shift in 0..16 {
+        let mut alternitives1 = vec![];
+        let mut alternitives2 = vec![];
+        for v in 0..256 {
+            let input = (v as u128) << (shift * 8);
+            let hasher1 = constructor(input, 0);
+            let hasher2 = constructor(0, input);
+            let h1 = item.get_hash(hasher1);
+            let h2 = item.get_hash(hasher2);
+            alternitives1.push(h1);
+            alternitives2.push(h2);
+        }
+        assert_each_byte_differs(base, alternitives1);
+        assert_each_byte_differs(base, alternitives2);
+    }
+}
+
+fn assert_each_byte_differs(base: u64, alternitives: Vec<u64>) {
+    let mut changed_bits = 0_u64;
+    for alternitive in alternitives {
+        changed_bits |= base ^ alternitive
+    }
+    assert_eq!(core::u64::MAX, changed_bits, "Bits changed: {:x}", changed_bits);
+}
+
+fn test_finish_is_consistent<T: Hasher>(constructor: impl Fn(u128, u128) -> T) {
+    let mut hasher = constructor(1, 2);
+    "Foo".hash(&mut hasher);
+    let a = hasher.finish();
+    let b = hasher.finish();
+    assert_eq!(a, b);
+}
+
+fn test_single_key_bit_flip<T: Hasher>(constructor: impl Fn(u128, u128) -> T) {
+    for bit in 0..128 {
+        let mut a = constructor(0, 0);
+        let mut b = constructor(0, 1 << bit);
+        let mut c = constructor(1 << bit, 0);
+        "1234".hash(&mut a);
+        "1234".hash(&mut b);
+        "1234".hash(&mut c);
+        assert_sufficiently_different(a.finish(), b.finish(), 2);
+        assert_sufficiently_different(a.finish(), c.finish(), 2);
+        assert_sufficiently_different(b.finish(), c.finish(), 2);
+        let mut a = constructor(0, 0);
+        let mut b = constructor(0, 1 << bit);
+        let mut c = constructor(1 << bit, 0);
+        "12345678".hash(&mut a);
+        "12345678".hash(&mut b);
+        "12345678".hash(&mut c);
+        assert_sufficiently_different(a.finish(), b.finish(), 2);
+        assert_sufficiently_different(a.finish(), c.finish(), 2);
+        assert_sufficiently_different(b.finish(), c.finish(), 2);
+        let mut a = constructor(0, 0);
+        let mut b = constructor(0, 1 << bit);
+        let mut c = constructor(1 << bit, 0);
+        "1234567812345678".hash(&mut a);
+        "1234567812345678".hash(&mut b);
+        "1234567812345678".hash(&mut c);
+        assert_sufficiently_different(a.finish(), b.finish(), 2);
+        assert_sufficiently_different(a.finish(), c.finish(), 2);
+        assert_sufficiently_different(b.finish(), c.finish(), 2);
+    }
+}
+
+fn test_all_bytes_matter<T: HasherExt>(hasher: impl Fn() -> T) {
+    let mut item = vec![0; 256];
+    let base_hash = hash(&item, &hasher);
+    for pos in 0..256 {
+        item[pos] = 255;
+        let hash = hash(&item, &hasher);
+        assert_ne!(base_hash, hash, "Position {} did not affect output", pos);
+        item[pos] = 0;
+    }
+}
+
+fn test_no_pair_collisions<T: HasherExt>(hasher: impl Fn() -> T) {
+    let base = [0_u64, 0_u64];
+    let base_hash = hash(&base, &hasher);
+    for bitpos1 in 0..64 {
+        let a = 1_u64 << bitpos1;
+        for bitpos2 in 0..bitpos1 {
+            let b = 1_u64 << bitpos2;
+            let aa = hash(&[a, a], &hasher);
+            let ab = hash(&[a, b], &hasher);
+            let ba = hash(&[b, a], &hasher);
+            let bb = hash(&[b, b], &hasher);
+            assert_sufficiently_different(base_hash, aa, 3);
+            assert_sufficiently_different(base_hash, ab, 3);
+            assert_sufficiently_different(base_hash, ba, 3);
+            assert_sufficiently_different(base_hash, bb, 3);
+            assert_sufficiently_different(aa, ab, 3);
+            assert_sufficiently_different(ab, ba, 3);
+            assert_sufficiently_different(ba, bb, 3);
+            assert_sufficiently_different(aa, ba, 3);
+            assert_sufficiently_different(ab, bb, 3);
+            assert_sufficiently_different(aa, bb, 3);
+        }
+    }
+}
+
+fn hash<H: Hash, T: HasherExt>(b: &H, hasher: &dyn Fn() -> T) -> u64 {
+    b.get_hash(hasher())
+}
+
+fn test_single_bit_flip<T: HasherExt>(hasher: impl Fn() -> T) {
+    let size = 32;
+    let compare_value = hash(&0u32, &hasher);
+    for pos in 0..size {
+        let test_value = hash(&(1u32 << pos), &hasher);
+        assert_sufficiently_different(compare_value, test_value, 2);
+    }
+    let size = 64;
+    let compare_value = hash(&0u64, &hasher);
+    for pos in 0..size {
+        let test_value = hash(&(1u64 << pos), &hasher);
+        assert_sufficiently_different(compare_value, test_value, 2);
+    }
+    let size = 128;
+    let compare_value = hash(&0u128, &hasher);
+    for pos in 0..size {
+        let test_value = hash(&(1u128 << pos), &hasher);
+        dbg!(compare_value, test_value);
+        assert_sufficiently_different(compare_value, test_value, 2);
+    }
+}
+
+fn test_padding_doesnot_collide<T: Hasher>(hasher: impl Fn() -> T) {
+    for c in 0..128u8 {
+        for string in ["", "\0", "\x01", "1234", "12345678", "1234567812345678"].iter() {
+            let mut short = hasher();
+            string.hash(&mut short);
+            let value = short.finish();
+            let mut padded = string.to_string();
+            for num in 1..=128 {
+                let mut long = hasher();
+                padded.push(c as char);
+                padded.hash(&mut long);
+                let (same_bytes, same_nibbles) = count_same_bytes_and_nibbles(value, long.finish());
+                assert!(
+                    same_bytes <= 3,
+                    format!("{} bytes of {} -> {:x} vs {:x}", num, c, value, long.finish())
+                );
+                assert!(
+                    same_nibbles <= 8,
+                    format!("{} bytes of {} -> {:x} vs {:x}", num, c, value, long.finish())
+                );
+                let flipped_bits = (value ^ long.finish()).count_ones();
+                assert!(flipped_bits > 10);
+            }
+            if string.len() > 0 {
+                let mut padded = string[1..].to_string();
+                padded.push(c as char);
+                for num in 2..=128 {
+                    let mut long = hasher();
+                    padded.push(c as char);
+                    padded.hash(&mut long);
+                    let (same_bytes, same_nibbles) = count_same_bytes_and_nibbles(value, long.finish());
+                    assert!(
+                        same_bytes <= 3,
+                        format!(
+                            "string {:?} + {} bytes of {} -> {:x} vs {:x}",
+                            string,
+                            num,
+                            c,
+                            value,
+                            long.finish()
+                        )
+                    );
+                    assert!(
+                        same_nibbles <= 8,
+                        format!(
+                            "string {:?} + {} bytes of {} -> {:x} vs {:x}",
+                            string,
+                            num,
+                            c,
+                            value,
+                            long.finish()
+                        )
+                    );
+                    let flipped_bits = (value ^ long.finish()).count_ones();
+                    assert!(flipped_bits > 10);
+                }
+            }
+        }
+    }
+}
+
+#[cfg(test)]
+mod fallback_tests {
+    use crate::fallback_hash::*;
+    use crate::hash_quality_test::*;
+
+    #[test]
+    fn fallback_single_bit_flip() {
+        test_single_bit_flip(|| AHasher::new_with_keys(0, 0))
+    }
+
+    #[test]
+    fn fallback_single_key_bit_flip() {
+        test_single_key_bit_flip(AHasher::new_with_keys)
+    }
+
+    #[test]
+    fn fallback_all_bytes_matter() {
+        test_all_bytes_matter(|| AHasher::new_with_keys(0, 0));
+    }
+
+    #[test]
+    fn fallback_test_no_pair_collisions() {
+        test_no_pair_collisions(|| AHasher::new_with_keys(0, 0));
+    }
+
+    #[test]
+    fn fallback_test_no_full_collisions() {
+        test_no_full_collisions(|| AHasher::new_with_keys(12345, 67890));
+    }
+
+    #[test]
+    fn fallback_keys_change_output() {
+        test_keys_change_output(AHasher::new_with_keys);
+    }
+
+    #[test]
+    fn fallback_input_affect_every_byte() {
+        test_input_affect_every_byte(AHasher::new_with_keys);
+    }
+
+    #[test]
+    fn fallback_keys_affect_every_byte() {
+        //For fallback second key is not used in every hash.
+        #[cfg(not(feature = "specialize"))]
+        test_keys_affect_every_byte(0, |a, b| AHasher::new_with_keys(a ^ b, a));
+        test_keys_affect_every_byte("", |a, b| AHasher::new_with_keys(a ^ b, a));
+        test_keys_affect_every_byte((0, 0), |a, b| AHasher::new_with_keys(a ^ b, a));
+    }
+
+    #[test]
+    fn fallback_finish_is_consistant() {
+        test_finish_is_consistent(AHasher::new_with_keys)
+    }
+
+    #[test]
+    fn fallback_padding_doesnot_collide() {
+        test_padding_doesnot_collide(|| AHasher::new_with_keys(0, 0));
+        test_padding_doesnot_collide(|| AHasher::new_with_keys(0, 1));
+        test_padding_doesnot_collide(|| AHasher::new_with_keys(1, 0));
+        test_padding_doesnot_collide(|| AHasher::new_with_keys(1, 1));
+    }
+}
+
+///Basic sanity tests of the cypto properties of aHash.
+#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes", not(miri)))]
+#[cfg(test)]
+mod aes_tests {
+    use crate::aes_hash::*;
+    use crate::hash_quality_test::*;
+    use std::hash::{Hash, Hasher};
+
+    const BAD_KEY: u128 = 0x5252_5252_5252_5252_5252_5252_5252_5252; //This encrypts to 0.
+    const BAD_KEY2: u128 = 0x6363_6363_6363_6363_6363_6363_6363_6363; //This decrypts to 0.
+
+    #[test]
+    fn test_single_bit_in_byte() {
+        let mut hasher1 = AHasher::new_with_keys(0, 0);
+        8_u32.hash(&mut hasher1);
+        let mut hasher2 = AHasher::new_with_keys(0, 0);
+        0_u32.hash(&mut hasher2);
+        assert_sufficiently_different(hasher1.finish(), hasher2.finish(), 1);
+    }
+
+    #[test]
+    fn aes_single_bit_flip() {
+        test_single_bit_flip(|| AHasher::new_with_keys(BAD_KEY, BAD_KEY));
+        test_single_bit_flip(|| AHasher::new_with_keys(BAD_KEY2, BAD_KEY2));
+    }
+
+    #[test]
+    fn aes_single_key_bit_flip() {
+        test_single_key_bit_flip(AHasher::new_with_keys)
+    }
+
+    #[test]
+    fn aes_all_bytes_matter() {
+        test_all_bytes_matter(|| AHasher::new_with_keys(BAD_KEY, BAD_KEY));
+        test_all_bytes_matter(|| AHasher::new_with_keys(BAD_KEY2, BAD_KEY2));
+    }
+
+    #[test]
+    fn aes_test_no_pair_collisions() {
+        test_no_pair_collisions(|| AHasher::new_with_keys(BAD_KEY, BAD_KEY));
+        test_no_pair_collisions(|| AHasher::new_with_keys(BAD_KEY2, BAD_KEY2));
+    }
+
+    #[test]
+    fn ase_test_no_full_collisions() {
+        test_no_full_collisions(|| AHasher::new_with_keys(12345, 67890));
+    }
+
+    #[test]
+    fn aes_keys_change_output() {
+        test_keys_change_output(AHasher::new_with_keys);
+    }
+
+    #[test]
+    fn aes_input_affect_every_byte() {
+        test_input_affect_every_byte(AHasher::new_with_keys);
+    }
+
+    #[test]
+    fn aes_keys_affect_every_byte() {
+        #[cfg(not(feature = "specialize"))]
+        test_keys_affect_every_byte(0, AHasher::new_with_keys);
+        test_keys_affect_every_byte("", AHasher::new_with_keys);
+        test_keys_affect_every_byte((0, 0), AHasher::new_with_keys);
+    }
+    #[test]
+    fn aes_finish_is_consistant() {
+        test_finish_is_consistent(AHasher::new_with_keys)
+    }
+
+    #[test]
+    fn aes_padding_doesnot_collide() {
+        test_padding_doesnot_collide(|| AHasher::new_with_keys(BAD_KEY, BAD_KEY));
+        test_padding_doesnot_collide(|| AHasher::new_with_keys(BAD_KEY2, BAD_KEY2));
+    }
+}
diff --git a/src/hash_set.rs b/src/hash_set.rs
new file mode 100644
index 0000000..576af34
--- /dev/null
+++ b/src/hash_set.rs
@@ -0,0 +1,269 @@
+use crate::{RandomState};
+use std::collections::{hash_set, HashSet};
+use std::fmt::{self, Debug};
+use std::hash::{BuildHasher, Hash};
+use std::iter::FromIterator;
+use std::ops::{BitAnd, BitOr, BitXor, Deref, DerefMut, Sub};
+
+/// A [`HashSet`](std::collections::HashSet) using [`RandomState`](crate::RandomState) to hash the items.
+/// (Requires the `std` feature to be enabled.)
+#[derive(Clone)]
+pub struct AHashSet<T, S = crate::RandomState>(HashSet<T, S>);
+
+impl<T> From<HashSet<T, crate::RandomState>> for AHashSet<T> {
+    fn from(item: HashSet<T, crate::RandomState>) -> Self {
+        AHashSet(item)
+    }
+}
+
+impl<T> Into<HashSet<T, crate::RandomState>> for AHashSet<T> {
+    fn into(self) -> HashSet<T, crate::RandomState> {
+        self.0
+    }
+}
+
+impl<T> AHashSet<T, RandomState> {
+    pub fn new() -> Self {
+        AHashSet(HashSet::with_hasher(RandomState::default()))
+    }
+
+    pub fn with_capacity(capacity: usize) -> Self {
+        AHashSet(HashSet::with_capacity_and_hasher(capacity, RandomState::default()))
+    }
+}
+
+impl<T, S> AHashSet<T, S> where S: BuildHasher {
+
+    pub fn with_hasher(hash_builder: S) -> Self {
+        AHashSet(HashSet::with_hasher(hash_builder))
+    }
+
+    pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self {
+        AHashSet(HashSet::with_capacity_and_hasher(capacity, hash_builder))
+    }
+}
+
+impl<T, S> Deref for AHashSet<T, S> {
+    type Target = HashSet<T, S>;
+    fn deref(&self) -> &Self::Target {
+        &self.0
+    }
+}
+
+impl<T, S> DerefMut for AHashSet<T, S> {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        &mut self.0
+    }
+}
+
+impl<T, S> PartialEq for AHashSet<T, S>
+where
+    T: Eq + Hash,
+    S: BuildHasher,
+{
+    fn eq(&self, other: &AHashSet<T, S>) -> bool {
+        self.0.eq(&other.0)
+    }
+}
+
+impl<T, S> Eq for AHashSet<T, S>
+where
+    T: Eq + Hash,
+    S: BuildHasher,
+{
+}
+
+impl<T, S> BitOr<&AHashSet<T, S>> for &AHashSet<T, S>
+where
+    T: Eq + Hash + Clone,
+    S: BuildHasher + Default,
+{
+    type Output = AHashSet<T, S>;
+
+    /// Returns the union of `self` and `rhs` as a new `AHashSet<T, S>`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use ahash::AHashSet;
+    ///
+    /// let a: AHashSet<_> = vec![1, 2, 3].into_iter().collect();
+    /// let b: AHashSet<_> = vec![3, 4, 5].into_iter().collect();
+    ///
+    /// let set = &a | &b;
+    ///
+    /// let mut i = 0;
+    /// let expected = [1, 2, 3, 4, 5];
+    /// for x in &set {
+    ///     assert!(expected.contains(x));
+    ///     i += 1;
+    /// }
+    /// assert_eq!(i, expected.len());
+    /// ```
+    fn bitor(self, rhs: &AHashSet<T, S>) -> AHashSet<T, S> {
+        AHashSet(self.0.bitor(&rhs.0))
+    }
+}
+
+impl<T, S> BitAnd<&AHashSet<T, S>> for &AHashSet<T, S>
+where
+    T: Eq + Hash + Clone,
+    S: BuildHasher + Default,
+{
+    type Output = AHashSet<T, S>;
+
+    /// Returns the intersection of `self` and `rhs` as a new `AHashSet<T, S>`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use ahash::AHashSet;
+    ///
+    /// let a: AHashSet<_> = vec![1, 2, 3].into_iter().collect();
+    /// let b: AHashSet<_> = vec![2, 3, 4].into_iter().collect();
+    ///
+    /// let set = &a & &b;
+    ///
+    /// let mut i = 0;
+    /// let expected = [2, 3];
+    /// for x in &set {
+    ///     assert!(expected.contains(x));
+    ///     i += 1;
+    /// }
+    /// assert_eq!(i, expected.len());
+    /// ```
+    fn bitand(self, rhs: &AHashSet<T, S>) -> AHashSet<T, S> {
+        AHashSet(self.0.bitand(&rhs.0))
+    }
+}
+
+impl<T, S> BitXor<&AHashSet<T, S>> for &AHashSet<T, S>
+where
+    T: Eq + Hash + Clone,
+    S: BuildHasher + Default,
+{
+    type Output = AHashSet<T, S>;
+
+    /// Returns the symmetric difference of `self` and `rhs` as a new `AHashSet<T, S>`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use ahash::AHashSet;
+    ///
+    /// let a: AHashSet<_> = vec![1, 2, 3].into_iter().collect();
+    /// let b: AHashSet<_> = vec![3, 4, 5].into_iter().collect();
+    ///
+    /// let set = &a ^ &b;
+    ///
+    /// let mut i = 0;
+    /// let expected = [1, 2, 4, 5];
+    /// for x in &set {
+    ///     assert!(expected.contains(x));
+    ///     i += 1;
+    /// }
+    /// assert_eq!(i, expected.len());
+    /// ```
+    fn bitxor(self, rhs: &AHashSet<T, S>) -> AHashSet<T, S> {
+        AHashSet(self.0.bitxor(&rhs.0))
+    }
+}
+
+impl<T, S> Sub<&AHashSet<T, S>> for &AHashSet<T, S>
+where
+    T: Eq + Hash + Clone,
+    S: BuildHasher + Default,
+{
+    type Output = AHashSet<T, S>;
+
+    /// Returns the difference of `self` and `rhs` as a new `AHashSet<T, S>`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use ahash::AHashSet;
+    ///
+    /// let a: AHashSet<_> = vec![1, 2, 3].into_iter().collect();
+    /// let b: AHashSet<_> = vec![3, 4, 5].into_iter().collect();
+    ///
+    /// let set = &a - &b;
+    ///
+    /// let mut i = 0;
+    /// let expected = [1, 2];
+    /// for x in &set {
+    ///     assert!(expected.contains(x));
+    ///     i += 1;
+    /// }
+    /// assert_eq!(i, expected.len());
+    /// ```
+    fn sub(self, rhs: &AHashSet<T, S>) -> AHashSet<T, S> {
+        AHashSet(self.0.sub(&rhs.0))
+    }
+}
+
+impl<T, S> Debug for AHashSet<T, S>
+where
+    T: Debug,
+    S: BuildHasher,
+{
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        self.0.fmt(fmt)
+    }
+}
+
+impl<T, S> FromIterator<T> for AHashSet<T, S>
+where
+    T: Eq + Hash,
+    S: BuildHasher + Default,
+{
+    #[inline]
+    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> AHashSet<T, S> {
+        AHashSet(HashSet::from_iter(iter))
+    }
+}
+
+impl<'a, T, S> IntoIterator for &'a AHashSet<T, S> {
+    type Item = &'a T;
+    type IntoIter = hash_set::Iter<'a, T>;
+    fn into_iter(self) -> Self::IntoIter {
+        (&self.0).iter()
+    }
+}
+
+impl<T, S> IntoIterator for AHashSet<T, S> {
+    type Item = T;
+    type IntoIter = hash_set::IntoIter<T>;
+    fn into_iter(self) -> Self::IntoIter {
+        self.0.into_iter()
+    }
+}
+
+impl<T, S> Extend<T> for AHashSet<T, S>
+where
+    T: Eq + Hash,
+    S: BuildHasher,
+{
+    #[inline]
+    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
+        self.0.extend(iter)
+    }
+}
+
+impl<'a, T, S> Extend<&'a T> for AHashSet<T, S>
+where
+    T: 'a + Eq + Hash + Copy,
+    S: BuildHasher,
+{
+    #[inline]
+    fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
+        self.0.extend(iter)
+    }
+}
+
+impl<T> Default for AHashSet<T, RandomState> {
+    /// Creates an empty `AHashSet<T, S>` with the `Default` value for the hasher.
+    #[inline]
+    fn default() -> AHashSet<T, RandomState> {
+        AHashSet(HashSet::default())
+    }
+}
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..2d5c5c0
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,190 @@
+//! AHash is a hashing algorithm is intended to be a high performance, (hardware specific), keyed hash function.
+//! This can be seen as a DOS resistant alternative to `FxHash`, or a fast equivalent to `SipHash`.
+//! It provides a high speed hash algorithm, but where the result is not predictable without knowing a Key.
+//! This allows it to be used in a `HashMap` without allowing for the possibility that an malicious user can
+//! induce a collision.
+//!
+//! # How aHash works
+//!
+//! aHash uses the hardware AES instruction on x86 processors to provide a keyed hash function.
+//! aHash is not a cryptographically secure hash.
+//!
+//! # Example
+//! ```
+//! use ahash::{AHasher, RandomState};
+//! use std::collections::HashMap;
+//!
+//! let mut map: HashMap<i32, i32, RandomState> = HashMap::default();
+//! map.insert(12, 34);
+//! ```
+//! For convinence wrappers called `AHashMap` and `AHashSet` are also provided.
+//! These to the same thing with slightly less typing.
+//! ```ignore
+//! use ahash::AHashMap;
+//!
+//! let mut map: AHashMap<i32, i32> = AHashMap::with_capacity(4);
+//! map.insert(12, 34);
+//! map.insert(56, 78);
+//! ```
+#![deny(clippy::correctness, clippy::complexity, clippy::perf)]
+#![allow(clippy::pedantic, clippy::cast_lossless, clippy::unreadable_literal)]
+#![cfg_attr(all(not(test), not(feature = "std")), no_std)]
+#![cfg_attr(feature = "specialize", feature(specialization))]
+
+#[macro_use]
+mod convert;
+
+#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes", not(miri)))]
+mod aes_hash;
+mod fallback_hash;
+#[cfg(test)]
+mod hash_quality_test;
+
+mod operations;
+#[cfg(feature = "std")]
+mod hash_map;
+#[cfg(feature = "std")]
+mod hash_set;
+mod random_state;
+mod specialize;
+
+#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes", not(miri)))]
+pub use crate::aes_hash::AHasher;
+
+#[cfg(not(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes", not(miri))))]
+pub use crate::fallback_hash::AHasher;
+pub use crate::random_state::RandomState;
+
+pub use crate::specialize::CallHasher;
+
+#[cfg(feature = "std")]
+pub use crate::hash_map::AHashMap;
+#[cfg(feature = "std")]
+pub use crate::hash_set::AHashSet;
+use core::hash::Hasher;
+use core::hash::BuildHasher;
+
+/// Provides a default [Hasher] with fixed keys.
+/// This is typically used in conjunction with [BuildHasherDefault] to create
+/// [AHasher]s in order to hash the keys of the map.
+///
+/// Generally it is preferable to use [RandomState] instead, so that different
+/// hashmaps will have different keys. However if fixed keys are desireable this
+/// may be used instead.
+///
+/// # Example
+/// ```
+/// use std::hash::BuildHasherDefault;
+/// use ahash::{AHasher, RandomState};
+/// use std::collections::HashMap;
+///
+/// let mut map: HashMap<i32, i32, BuildHasherDefault<AHasher>> = HashMap::default();
+/// map.insert(12, 34);
+/// ```
+///
+/// [BuildHasherDefault]: std::hash::BuildHasherDefault
+/// [Hasher]: std::hash::Hasher
+/// [HashMap]: std::collections::HashMap
+impl Default for AHasher {
+
+    /// Constructs a new [AHasher] with fixed keys.
+    /// If `std` is enabled these will be generated upon first invocation.
+    /// Otherwise if the `compile-time-rng`feature is enabled these will be generated at compile time.
+    /// If neither of these features are available, hardcoded constants will be used.
+    /// 
+    /// Because the values are fixed, different hashers will all hash elements the same way.
+    /// This could make hash values predictable, if DOS attacks are a concern. If this behaviour is
+    /// not required, it may be preferable to use [RandomState] instead.
+    /// 
+    /// # Examples
+    ///
+    /// ```
+    /// use ahash::AHasher;
+    /// use std::hash::Hasher;
+    ///
+    /// let mut hasher_1 = AHasher::default();
+    /// let mut hasher_2 = AHasher::default();
+    ///
+    /// hasher_1.write_u32(1234);
+    /// hasher_2.write_u32(1234);
+    ///
+    /// assert_eq!(hasher_1.finish(), hasher_2.finish());
+    /// ```
+    #[inline]
+    fn default() -> AHasher {
+        RandomState::with_fixed_keys().build_hasher()
+    }
+}
+
+/// Used for specialization. (Sealed)
+pub(crate) trait HasherExt: Hasher {
+    #[doc(hidden)]
+    fn hash_u64(self, value: u64) -> u64;
+
+    #[doc(hidden)]
+    fn short_finish(&self) -> u64;
+}
+
+impl<T: Hasher> HasherExt for T {
+    #[inline]
+    #[cfg(feature = "specialize")]
+    default fn hash_u64(self, value: u64) -> u64 {
+        value.get_hash(self)
+    }
+    #[inline]
+    #[cfg(not(feature = "specialize"))]
+    fn hash_u64(self, value: u64) -> u64 {
+        value.get_hash(self)
+    }
+    #[inline]
+    #[cfg(feature = "specialize")]
+    default fn short_finish(&self) -> u64 {
+        self.finish()
+    }
+    #[inline]
+    #[cfg(not(feature = "specialize"))]
+    fn short_finish(&self) -> u64 {
+        self.finish()
+    }
+}
+
+// #[inline(never)]
+// #[doc(hidden)]
+// pub fn hash_test(input: &[u8]) -> u64 {
+//     let a = AHasher::new_with_keys(11111111111_u128, 2222222222_u128);
+//     input.get_hash(a)
+// }
+
+#[cfg(feature = "std")]
+#[cfg(test)]
+mod test {
+    use crate::convert::Convert;
+    use crate::*;
+    use std::collections::HashMap;
+
+    #[test]
+    fn test_default_builder() {
+        use core::hash::BuildHasherDefault;
+
+        let mut map = HashMap::<u32, u64, BuildHasherDefault<AHasher>>::default();
+        map.insert(1, 3);
+    }
+
+    #[test]
+    fn test_builder() {
+        let mut map = HashMap::<u32, u64, RandomState>::default();
+        map.insert(1, 3);
+    }
+
+    #[test]
+    fn test_conversion() {
+        let input: &[u8] = b"dddddddd";
+        let bytes: u64 = as_array!(input, 8).convert();
+        assert_eq!(bytes, 0x6464646464646464);
+    }
+
+    #[test]
+    fn test_ahasher_construction() {
+        let _ = AHasher::new_with_keys(1234, 5678);
+    }
+}
diff --git a/src/operations.rs b/src/operations.rs
new file mode 100644
index 0000000..0646c44
--- /dev/null
+++ b/src/operations.rs
@@ -0,0 +1,277 @@
+use crate::convert::*;
+
+/// This is a constant with a lot of special properties found by automated search.
+/// See the unit tests below. (Below are alternative values)
+#[cfg(all(target_feature = "ssse3", not(miri)))]
+const SHUFFLE_MASK: u128 = 0x020a0700_0c01030e_050f0d08_06090b04_u128;
+//const SHUFFLE_MASK: u128 = 0x000d0702_0a040301_05080f0c_0e0b0609_u128;
+//const SHUFFLE_MASK: u128 = 0x040A0700_030E0106_0D050F08_020B0C09_u128;
+
+pub(crate) const fn folded_multiply(s: u64, by: u64) -> u64 {
+    let result = (s as u128).wrapping_mul(by as u128);
+    ((result & 0xffff_ffff_ffff_ffff) as u64) ^ ((result >> 64) as u64)
+}
+
+#[inline(always)]
+pub(crate) fn shuffle(a: u128) -> u128 {
+    #[cfg(all(target_feature = "ssse3", not(miri)))]
+        {
+            use core::mem::transmute;
+            #[cfg(target_arch = "x86")]
+            use core::arch::x86::*;
+            #[cfg(target_arch = "x86_64")]
+            use core::arch::x86_64::*;
+            unsafe {
+                transmute(_mm_shuffle_epi8(transmute(a), transmute(SHUFFLE_MASK)))
+            }
+        }
+    #[cfg(not(all(target_feature = "ssse3", not(miri))))]
+        {
+            a.swap_bytes()
+        }
+}
+
+#[allow(unused)] //not used by fallback
+#[inline(always)]
+pub(crate) fn add_and_shuffle(a: u128, b: u128) -> u128 {
+    let sum = add_by_64s(a.convert(), b.convert());
+    shuffle(sum.convert())
+}
+
+#[allow(unused)] //not used by fallbac
+#[inline(always)]
+pub(crate) fn shuffle_and_add(base: u128, to_add: u128) -> u128 {
+    let shuffled: [u64; 2] = shuffle(base).convert();
+    add_by_64s(shuffled, to_add.convert()).convert()
+}
+
+#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "sse2", not(miri)))]
+#[inline(always)]
+pub(crate) fn add_by_64s(a: [u64; 2], b: [u64; 2]) -> [u64; 2] {
+    use core::mem::transmute;
+    unsafe {
+        #[cfg(target_arch = "x86")]
+        use core::arch::x86::*;
+        #[cfg(target_arch = "x86_64")]
+        use core::arch::x86_64::*;
+        transmute(_mm_add_epi64(transmute(a), transmute(b)))
+    }
+}
+
+#[cfg(not(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "sse2", not(miri))))]
+#[inline(always)]
+pub(crate) fn add_by_64s(a: [u64; 2], b: [u64; 2]) -> [u64; 2] {
+    [a[0].wrapping_add(b[0]), a[1].wrapping_add(b[1])]
+}
+
+#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes", not(miri)))]
+#[allow(unused)]
+#[inline(always)]
+pub(crate) fn aesenc(value: u128, xor: u128) -> u128 {
+    #[cfg(target_arch = "x86")]
+    use core::arch::x86::*;
+    #[cfg(target_arch = "x86_64")]
+    use core::arch::x86_64::*;
+    use core::mem::transmute;
+    unsafe {
+        let value = transmute(value);
+        transmute(_mm_aesenc_si128(value, transmute(xor)))
+    }
+}
+#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes", not(miri)))]
+#[allow(unused)]
+#[inline(always)]
+pub(crate) fn aesdec(value: u128, xor: u128) -> u128 {
+    #[cfg(target_arch = "x86")]
+    use core::arch::x86::*;
+    #[cfg(target_arch = "x86_64")]
+    use core::arch::x86_64::*;
+    use core::mem::transmute;
+    unsafe {
+        let value = transmute(value);
+        transmute(_mm_aesdec_si128(value, transmute(xor)))
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+    use crate::convert::Convert;
+
+    // This is code to search for the shuffle constant
+    //
+    //thread_local! { static MASK: Cell<u128> = Cell::new(0); }
+    //
+    // fn shuffle(a: u128) -> u128 {
+    //     use std::intrinsics::transmute;
+    //     #[cfg(target_arch = "x86")]
+    //     use core::arch::x86::*;
+    //     #[cfg(target_arch = "x86_64")]
+    //     use core::arch::x86_64::*;
+    //     MASK.with(|mask| {
+    //         unsafe { transmute(_mm_shuffle_epi8(transmute(a), transmute(mask.get()))) }
+    //     })
+    // }
+    //
+    // #[test]
+    // fn find_shuffle() {
+    //     use rand::prelude::*;
+    //     use SliceRandom;
+    //     use std::panic;
+    //     use std::io::Write;
+    //
+    //     let mut value: [u8; 16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ,13, 14, 15];
+    //     let mut rand = thread_rng();
+    //     let mut successful_list = HashMap::new();
+    //     for _attempt in 0..10000000 {
+    //         rand.shuffle(&mut value);
+    //         let test_val = value.convert();
+    //         MASK.with(|mask| {
+    //             mask.set(test_val);
+    //         });
+    //         if let Ok(successful) = panic::catch_unwind(|| {
+    //             test_shuffle_does_not_collide_with_aes();
+    //             test_shuffle_moves_high_bits();
+    //             test_shuffle_moves_every_value();
+    //             //test_shuffle_does_not_loop();
+    //             value
+    //         }) {
+    //             let successful: u128 = successful.convert();
+    //             successful_list.insert(successful, iters_before_loop());
+    //         }
+    //     }
+    //     let write_file = File::create("/tmp/output").unwrap();
+    //     let mut writer = BufWriter::new(&write_file);
+    //
+    //     for success in successful_list {
+    //         writeln!(writer, "Found successful: {:x?} - {:?}", success.0, success.1);
+    //     }
+    // }
+    //
+    // fn iters_before_loop() -> u32 {
+    //     let numbered = 0x00112233_44556677_8899AABB_CCDDEEFF;
+    //     let mut shuffled = shuffle(numbered);
+    //     let mut count = 0;
+    //     loop {
+    //         // println!("{:>16x}", shuffled);
+    //         if numbered == shuffled {
+    //             break;
+    //         }
+    //         count += 1;
+    //         shuffled = shuffle(shuffled);
+    //     }
+    //     count
+    // }
+
+    #[cfg(all(
+        any(target_arch = "x86", target_arch = "x86_64"),
+        target_feature = "ssse3",
+        target_feature = "aes",
+        not(miri)
+    ))]
+    #[test]
+    fn test_shuffle_does_not_collide_with_aes() {
+        let mut value: [u8; 16] = [0; 16];
+        let zero_mask_enc = aesenc(0, 0);
+        let zero_mask_dec = aesdec(0, 0);
+        for index in 0..16 {
+            value[index] = 1;
+            let excluded_positions_enc: [u8; 16] = aesenc(value.convert(), zero_mask_enc).convert();
+            let excluded_positions_dec: [u8; 16] = aesdec(value.convert(), zero_mask_dec).convert();
+            let actual_location: [u8; 16] = shuffle(value.convert()).convert();
+            for pos in 0..16 {
+                if actual_location[pos] != 0 {
+                    assert_eq!(
+                        0, excluded_positions_enc[pos],
+                        "Forward Overlap between {:?} and {:?} at {}",
+                        excluded_positions_enc, actual_location, index
+                    );
+                    assert_eq!(
+                        0, excluded_positions_dec[pos],
+                        "Reverse Overlap between {:?} and {:?} at {}",
+                        excluded_positions_dec, actual_location, index
+                    );
+                }
+            }
+            value[index] = 0;
+        }
+    }
+
+    #[test]
+    fn test_shuffle_contains_each_value() {
+        let value: [u8; 16] = 0x00010203_04050607_08090A0B_0C0D0E0F_u128.convert();
+        let shuffled: [u8; 16] = shuffle(value.convert()).convert();
+        for index in 0..16_u8 {
+            assert!(shuffled.contains(&index), "Value is missing {}", index);
+        }
+    }
+
+    #[test]
+    fn test_shuffle_moves_every_value() {
+        let mut value: [u8; 16] = [0; 16];
+        for index in 0..16 {
+            value[index] = 1;
+            let shuffled: [u8; 16] = shuffle(value.convert()).convert();
+            assert_eq!(0, shuffled[index], "Value is not moved {}", index);
+            value[index] = 0;
+        }
+    }
+
+    #[test]
+    fn test_shuffle_moves_high_bits() {
+        assert!(
+            shuffle(1) > (1_u128 << 80),
+            "Low bits must be moved to other half {:?} -> {:?}",
+            0,
+            shuffle(1)
+        );
+
+        assert!(
+            shuffle(1_u128 << 58) >= (1_u128 << 64),
+            "High bits must be moved to other half {:?} -> {:?}",
+            7,
+            shuffle(1_u128 << 58)
+        );
+        assert!(
+            shuffle(1_u128 << 58) < (1_u128 << 112),
+            "High bits must not remain high {:?} -> {:?}",
+            7,
+            shuffle(1_u128 << 58)
+        );
+        assert!(
+            shuffle(1_u128 << 64) < (1_u128 << 64),
+            "Low bits must be moved to other half {:?} -> {:?}",
+            8,
+            shuffle(1_u128 << 64)
+        );
+        assert!(
+            shuffle(1_u128 << 64) >= (1_u128 << 16),
+            "Low bits must not remain low {:?} -> {:?}",
+            8,
+            shuffle(1_u128 << 64)
+        );
+
+        assert!(
+            shuffle(1_u128 << 120) < (1_u128 << 50),
+            "High bits must be moved to low half {:?} -> {:?}",
+            15,
+            shuffle(1_u128 << 120)
+        );
+    }
+
+    #[cfg(all(
+        any(target_arch = "x86", target_arch = "x86_64"),
+        target_feature = "ssse3",
+        not(miri)
+    ))]
+    #[test]
+    fn test_shuffle_does_not_loop() {
+        let numbered = 0x00112233_44556677_8899AABB_CCDDEEFF;
+        let mut shuffled = shuffle(numbered);
+        for count in 0..100 {
+            // println!("{:>16x}", shuffled);
+            assert_ne!(numbered, shuffled, "Equal after {} vs {:x}", count, shuffled);
+            shuffled = shuffle(shuffled);
+        }
+    }
+}
diff --git a/src/random_state.rs b/src/random_state.rs
new file mode 100644
index 0000000..8501cbd
--- /dev/null
+++ b/src/random_state.rs
@@ -0,0 +1,200 @@
+#[cfg(feature = "std")]
+use crate::convert::Convert;
+use crate::{AHasher};
+#[cfg(all(not(feature = "std"), feature = "compile-time-rng"))]
+use const_random::const_random;
+use core::fmt;
+use core::hash::BuildHasher;
+use core::hash::Hasher;
+#[cfg(feature = "std")]
+use lazy_static::*;
+use core::sync::atomic::{AtomicUsize, Ordering};
+
+#[cfg(feature = "std")]
+lazy_static! {
+    static ref SEEDS: [[u64; 4]; 2] = {
+        let mut result: [u8; 64] = [0; 64];
+        getrandom::getrandom(&mut result).expect("getrandom::getrandom() failed.");
+        result.convert()
+    };
+}
+
+static COUNTER: AtomicUsize = AtomicUsize::new(0);
+
+pub(crate) const PI: [u64; 4] = [
+    0x243f_6a88_85a3_08d3,
+    0x1319_8a2e_0370_7344,
+    0xa409_3822_299f_31d0,
+    0x082e_fa98_ec4e_6c89,
+];
+
+#[cfg(all(not(feature = "std"), not(feature = "compile-time-rng")))]
+const PI2: [u64; 4] = [
+    0x4528_21e6_38d0_1377,
+    0xbe54_66cf_34e9_0c6c,
+    0xc0ac_29b7_c97c_50dd,
+    0x3f84_d5b5_b547_0917,
+];
+
+#[inline]
+pub(crate) fn seeds() -> [u64; 4] {
+    #[cfg(feature = "std")]
+    { SEEDS[1] }
+    #[cfg(all(not(feature = "std"), feature = "compile-time-rng"))]
+    { [const_random!(u64), const_random!(u64), const_random!(u64), const_random!(u64)] }
+    #[cfg(all(not(feature = "std"), not(feature = "compile-time-rng")))]
+    { PI }
+}
+
+
+/// Provides a [Hasher] factory. This is typically used (e.g. by [HashMap]) to create
+/// [AHasher]s in order to hash the keys of the map. See `build_hasher` below.
+///
+/// [build_hasher]: ahash::
+/// [Hasher]: std::hash::Hasher
+/// [BuildHasher]: std::hash::BuildHasher
+/// [HashMap]: std::collections::HashMap
+#[derive(Clone)]
+pub struct RandomState {
+    pub(crate) k0: u64,
+    pub(crate) k1: u64,
+    pub(crate) k2: u64,
+    pub(crate) k3: u64,
+}
+
+impl fmt::Debug for RandomState {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.pad("RandomState { .. }")
+    }
+}
+
+impl RandomState {
+    /// Use randomly generated keys
+    #[inline]
+    pub fn new() -> RandomState {
+        #[cfg(feature = "std")]
+        {
+            let seeds = *SEEDS;
+            RandomState::from_keys(seeds[0], seeds[1])
+        }
+        #[cfg(all(not(feature = "std"), feature = "compile-time-rng"))]
+        {
+            RandomState::from_keys(
+                [const_random!(u64), const_random!(u64), const_random!(u64), const_random!(u64)],
+                [const_random!(u64), const_random!(u64), const_random!(u64), const_random!(u64)],
+            )
+        }
+        #[cfg(all(not(feature = "std"), not(feature = "compile-time-rng")))]
+        {
+            RandomState::from_keys(PI, PI2)
+        }
+    }
+
+    /// Allows for supplying seeds, but each time it is called the resulting state will be different.
+    /// This is done using a static counter, so it can safely be used with a fixed keys.
+    #[inline]
+    pub fn generate_with(k0: u64, k1: u64, k2: u64, k3: u64) -> RandomState {
+        RandomState::from_keys(seeds(), [k0, k1, k2, k3])
+    }
+
+    fn from_keys(a: [u64; 4], b: [u64; 4]) -> RandomState {
+        let [k0, k1, k2, k3] = a;
+        let mut hasher = AHasher::from_random_state(&RandomState { k0, k1, k2, k3 });
+
+        let stack_mem_loc = &hasher as *const _ as usize;
+        #[cfg(not(all(target_arch="arm", target_os="none")))]
+        {
+            hasher.write_usize(COUNTER.fetch_add(stack_mem_loc, Ordering::Relaxed));
+        }
+        #[cfg(all(target_arch="arm", target_os="none"))]
+        {
+            let previous = COUNTER.load(Ordering::Relaxed);
+            let new = previous.wrapping_add(stack_mem_loc);
+            COUNTER.store(new, Ordering::Relaxed);
+            hasher.write_usize(new);
+        }
+        #[cfg(all(not(feature = "std"), not(feature = "compile-time-rng")))]
+        hasher.write_usize(&PI as *const _ as usize);
+        let mix = |k: u64| {
+            let mut h = hasher.clone();
+            h.write_u64(k);
+            h.finish()
+        };
+
+        RandomState { k0: mix(b[0]), k1: mix(b[1]), k2: mix(b[2]), k3: mix(b[3]) }
+    }
+
+    /// Internal. Used by Default.
+    #[inline]
+    pub(crate) fn with_fixed_keys() -> RandomState {
+        let [k0, k1, k2, k3] = seeds();
+        RandomState { k0, k1, k2, k3 }
+    }
+
+    /// Allows for explicitly setting the seeds to used.
+    #[inline]
+    pub const fn with_seeds(k0: u64, k1: u64, k2: u64, k3: u64) -> RandomState {
+        RandomState { k0, k1, k2, k3 }
+    }
+}
+
+impl Default for RandomState {
+    #[inline]
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+impl BuildHasher for RandomState {
+    type Hasher = AHasher;
+
+    /// Constructs a new [AHasher] with keys based on this [RandomState] object.
+    /// This means that two different [RandomState]s will will generate
+    /// [AHasher]s that will return different hashcodes, but [Hasher]s created from the same [BuildHasher]
+    /// will generate the same hashes for the same input data.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use ahash::{AHasher, RandomState};
+    /// use std::hash::{Hasher, BuildHasher};
+    ///
+    /// let build_hasher = RandomState::new();
+    /// let mut hasher_1 = build_hasher.build_hasher();
+    /// let mut hasher_2 = build_hasher.build_hasher();
+    ///
+    /// hasher_1.write_u32(1234);
+    /// hasher_2.write_u32(1234);
+    ///
+    /// assert_eq!(hasher_1.finish(), hasher_2.finish());
+    ///
+    /// let other_build_hasher = RandomState::new();
+    /// let mut different_hasher = other_build_hasher.build_hasher();
+    /// different_hasher.write_u32(1234);
+    /// assert_ne!(different_hasher.finish(), hasher_1.finish());
+    /// ```
+    /// [Hasher]: std::hash::Hasher
+    /// [BuildHasher]: std::hash::BuildHasher
+    /// [HashMap]: std::collections::HashMap
+    #[inline]
+    fn build_hasher(&self) -> AHasher {
+        AHasher::from_random_state(self)
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+
+    #[test]
+    fn test_unique() {
+        let a = RandomState::new();
+        let b = RandomState::new();
+        assert_ne!(a.build_hasher().finish(), b.build_hasher().finish());
+    }
+
+    #[test]
+    fn test_with_seeds_const() {
+        const _CONST_RANDOM_STATE: RandomState = RandomState::with_seeds(17, 19, 21, 23);
+    }
+}
diff --git a/src/specialize.rs b/src/specialize.rs
new file mode 100644
index 0000000..9cc47cc
--- /dev/null
+++ b/src/specialize.rs
@@ -0,0 +1,205 @@
+#[cfg(feature = "specialize")]
+use crate::HasherExt;
+use core::hash::Hash;
+use core::hash::Hasher;
+
+/// Provides a way to get an optimized hasher for a given data type.
+/// Rather than using a Hasher generically which can hash any value, this provides a way to get a specialized hash
+/// for a specific type. So this may be faster for primitive types. It does however consume the hasher in the process.
+/// # Example
+/// ```
+/// use std::hash::BuildHasher;
+/// use ahash::RandomState;
+/// use ahash::CallHasher;
+///
+/// let hash_builder = RandomState::new();
+/// //...
+/// let value = 17;
+/// let hash = value.get_hash(hash_builder.build_hasher());
+/// ```
+pub trait CallHasher: Hash {
+    fn get_hash<H: Hasher>(&self, hasher: H) -> u64;
+}
+
+#[cfg(not(feature = "specialize"))]
+impl<T> CallHasher for T
+where
+    T: Hash,
+{
+    #[inline]
+    fn get_hash<H: Hasher>(&self, mut hasher: H) -> u64 {
+        self.hash(&mut hasher);
+        hasher.finish()
+    }
+}
+
+#[cfg(feature = "specialize")]
+impl<T> CallHasher for T
+where
+    T: Hash,
+{
+    #[inline]
+    default fn get_hash<H: Hasher>(&self, mut hasher: H) -> u64 {
+        self.hash(&mut hasher);
+        hasher.finish()
+    }
+}
+
+macro_rules! call_hasher_impl {
+    ($typ:ty) => {
+        #[cfg(feature = "specialize")]
+        impl CallHasher for $typ {
+            #[inline]
+            fn get_hash<H: Hasher>(&self, hasher: H) -> u64 {
+                hasher.hash_u64(*self as u64)
+            }
+        }
+        #[cfg(feature = "specialize")]
+        impl CallHasher for &$typ {
+            #[inline]
+            fn get_hash<H: Hasher>(&self, hasher: H) -> u64 {
+                hasher.hash_u64(**self as u64)
+            }
+        }
+    };
+}
+call_hasher_impl!(u8);
+call_hasher_impl!(u16);
+call_hasher_impl!(u32);
+call_hasher_impl!(u64);
+call_hasher_impl!(i8);
+call_hasher_impl!(i16);
+call_hasher_impl!(i32);
+call_hasher_impl!(i64);
+
+#[cfg(feature = "specialize")]
+impl CallHasher for u128 {
+    #[inline]
+    fn get_hash<H: Hasher>(&self, mut hasher: H) -> u64 {
+        hasher.write_u128(*self);
+        hasher.short_finish()
+    }
+}
+
+#[cfg(feature = "specialize")]
+impl CallHasher for i128 {
+    #[inline]
+    fn get_hash<H: Hasher>(&self, mut hasher: H) -> u64 {
+        hasher.write_u128(*self as u128);
+        hasher.short_finish()
+    }
+}
+
+#[cfg(feature = "specialize")]
+impl CallHasher for [u8] {
+    #[inline]
+    fn get_hash<H: Hasher>(&self, mut hasher: H) -> u64 {
+        hasher.write(self);
+        hasher.finish()
+    }
+}
+
+#[cfg(feature = "specialize")]
+impl CallHasher for &[u8] {
+    #[inline]
+    fn get_hash<H: Hasher>(&self, mut hasher: H) -> u64 {
+        hasher.write(self);
+        hasher.finish()
+    }
+}
+
+#[cfg(all(feature = "specialize", feature = "std"))]
+impl CallHasher for Vec<u8> {
+    #[inline]
+    fn get_hash<H: Hasher>(&self, mut hasher: H) -> u64 {
+        hasher.write(self);
+        hasher.finish()
+    }
+}
+
+#[cfg(all(feature = "specialize", feature = "std"))]
+impl CallHasher for &Vec<u8> {
+    #[inline]
+    fn get_hash<H: Hasher>(&self, mut hasher: H) -> u64 {
+        hasher.write(self);
+        hasher.finish()
+    }
+}
+
+#[cfg(feature = "specialize")]
+impl CallHasher for str {
+    #[inline]
+    fn get_hash<H: Hasher>(&self, mut hasher: H) -> u64 {
+        hasher.write(self.as_bytes());
+        hasher.finish()
+    }
+}
+
+#[cfg(feature = "specialize")]
+impl CallHasher for &str {
+    #[inline]
+    fn get_hash<H: Hasher>(&self, mut hasher: H) -> u64 {
+        hasher.write(self.as_bytes());
+        hasher.finish()
+    }
+}
+
+#[cfg(all(feature = "specialize", feature = "std"))]
+impl CallHasher for String {
+    #[inline]
+    fn get_hash<H: Hasher>(&self, mut hasher: H) -> u64 {
+        hasher.write(self.as_bytes());
+        hasher.finish()
+    }
+}
+
+#[cfg(all(feature = "specialize", feature = "std"))]
+impl CallHasher for &String {
+    #[inline]
+    fn get_hash<H: Hasher>(&self, mut hasher: H) -> u64 {
+        hasher.write(self.as_bytes());
+        hasher.finish()
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+    use crate::*;
+
+    #[test]
+    #[cfg(feature = "specialize")]
+    pub fn test_specialized_invoked() {
+        let shortened = 0_u64.get_hash(AHasher::new_with_keys(1, 2));
+        let mut hasher = AHasher::new_with_keys(1, 2);
+        0_u64.hash(&mut hasher);
+        assert_ne!(hasher.finish(), shortened);
+    }
+
+    /// Tests that some non-trivial transformation takes place.
+    #[test]
+    pub fn test_input_processed() {
+        let hasher = || AHasher::new_with_keys(3, 2);
+        assert_ne!(0, 0_u64.get_hash(hasher()));
+        assert_ne!(1, 0_u64.get_hash(hasher()));
+        assert_ne!(2, 0_u64.get_hash(hasher()));
+        assert_ne!(3, 0_u64.get_hash(hasher()));
+        assert_ne!(4, 0_u64.get_hash(hasher()));
+        assert_ne!(5, 0_u64.get_hash(hasher()));
+
+        assert_ne!(0, 1_u64.get_hash(hasher()));
+        assert_ne!(1, 1_u64.get_hash(hasher()));
+        assert_ne!(2, 1_u64.get_hash(hasher()));
+        assert_ne!(3, 1_u64.get_hash(hasher()));
+        assert_ne!(4, 1_u64.get_hash(hasher()));
+        assert_ne!(5, 1_u64.get_hash(hasher()));
+
+        let xored = 0_u64.get_hash(hasher()) ^ 1_u64.get_hash(hasher());
+        assert_ne!(0, xored);
+        assert_ne!(1, xored);
+        assert_ne!(2, xored);
+        assert_ne!(3, xored);
+        assert_ne!(4, xored);
+        assert_ne!(5, xored);
+    }
+}
diff --git a/tests/bench.rs b/tests/bench.rs
new file mode 100644
index 0000000..cb27667
--- /dev/null
+++ b/tests/bench.rs
@@ -0,0 +1,224 @@
+use ahash::{CallHasher, RandomState};
+use criterion::*;
+use fxhash::FxHasher;
+use std::collections::hash_map::DefaultHasher;
+use std::hash::{Hash, Hasher, BuildHasher};
+
+#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes"))]
+fn aeshash<H: Hash>(b: &H) -> u64 {
+    let hasher = RandomState::with_seeds(1, 2, 3, 4).build_hasher();
+    b.get_hash(hasher)
+}
+#[cfg(not(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes")))]
+fn aeshash<H: Hash>(_b: &H) -> u64 {
+    panic!("aes must be enabled")
+}
+
+#[cfg(not(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes")))]
+fn fallbackhash<H: Hash>(b: &H) -> u64 {
+    let hasher = RandomState::with_seeds(1, 2, 3, 4).build_hasher();
+    b.get_hash(hasher)
+}
+#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes"))]
+fn fallbackhash<H: Hash>(_b: &H) -> u64 {
+    panic!("aes must be disabled")
+}
+
+fn fnvhash<H: Hash>(b: &H) -> u64 {
+    let mut hasher = fnv::FnvHasher::default();
+    b.hash(&mut hasher);
+    hasher.finish()
+}
+
+fn siphash<H: Hash>(b: &H) -> u64 {
+    let mut hasher = DefaultHasher::default();
+    b.hash(&mut hasher);
+    hasher.finish()
+}
+
+fn fxhash<H: Hash>(b: &H) -> u64 {
+    let mut hasher = FxHasher::default();
+    b.hash(&mut hasher);
+    hasher.finish()
+}
+
+fn seahash<H: Hash>(b: &H) -> u64 {
+    let mut hasher = seahash::SeaHasher::default();
+    b.hash(&mut hasher);
+    hasher.finish()
+}
+
+const STRING_LENGTHS: [u32; 12] = [1, 3, 4, 7, 8, 15, 16, 24, 33, 68, 132, 1024];
+
+fn gen_strings() -> Vec<String> {
+    STRING_LENGTHS
+        .iter()
+        .map(|len| {
+            let mut string = String::default();
+            for pos in 1..=*len {
+                let c = (48 + (pos % 10) as u8) as char;
+                string.push(c);
+            }
+            string
+        })
+        .collect()
+}
+
+const U8_VALUES: [u8; 1] = [123];
+const U16_VALUES: [u16; 1] = [1234];
+const U32_VALUES: [u32; 1] = [12345678];
+const U64_VALUES: [u64; 1] = [1234567890123456];
+const U128_VALUES: [u128; 1] = [12345678901234567890123456789012];
+
+fn bench_ahash(c: &mut Criterion) {
+    c.bench(
+        "aeshash",
+        ParameterizedBenchmark::new("u8", |b, &s| b.iter(|| black_box(aeshash(s))), &U8_VALUES),
+    );
+    c.bench(
+        "aeshash",
+        ParameterizedBenchmark::new("u16", |b, &s| b.iter(|| black_box(aeshash(s))), &U16_VALUES),
+    );
+    c.bench(
+        "aeshash",
+        ParameterizedBenchmark::new("u32", |b, &s| b.iter(|| black_box(aeshash(s))), &U32_VALUES),
+    );
+    c.bench(
+        "aeshash",
+        ParameterizedBenchmark::new("u64", |b, &s| b.iter(|| black_box(aeshash(s))), &U64_VALUES),
+    );
+    c.bench(
+        "aeshash",
+        ParameterizedBenchmark::new("u128", |b, &s| b.iter(|| black_box(aeshash(s))), &U128_VALUES),
+    );
+    c.bench(
+        "aeshash",
+        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(aeshash(s))), gen_strings()),
+    );
+}
+
+fn bench_fallback(c: &mut Criterion) {
+    c.bench(
+        "fallback",
+        ParameterizedBenchmark::new("u8", |b, &s| b.iter(|| black_box(fallbackhash(s))), &U8_VALUES),
+    );
+    c.bench(
+        "fallback",
+        ParameterizedBenchmark::new("u16", |b, &s| b.iter(|| black_box(fallbackhash(s))), &U16_VALUES),
+    );
+    c.bench(
+        "fallback",
+        ParameterizedBenchmark::new("u32", |b, &s| b.iter(|| black_box(fallbackhash(s))), &U32_VALUES),
+    );
+    c.bench(
+        "fallback",
+        ParameterizedBenchmark::new("u64", |b, &s| b.iter(|| black_box(fallbackhash(s))), &U64_VALUES),
+    );
+    c.bench(
+        "fallback",
+        ParameterizedBenchmark::new("u128", |b, &s| b.iter(|| black_box(fallbackhash(s))), &U128_VALUES),
+    );
+    c.bench(
+        "fallback",
+        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(fallbackhash(s))), gen_strings()),
+    );
+}
+
+fn bench_fx(c: &mut Criterion) {
+    c.bench(
+        "fx",
+        ParameterizedBenchmark::new("u8", |b, &s| b.iter(|| black_box(fxhash(s))), &U8_VALUES),
+    );
+    c.bench(
+        "fx",
+        ParameterizedBenchmark::new("u16", |b, &s| b.iter(|| black_box(fxhash(s))), &U16_VALUES),
+    );
+    c.bench(
+        "fx",
+        ParameterizedBenchmark::new("u32", |b, &s| b.iter(|| black_box(fxhash(s))), &U32_VALUES),
+    );
+    c.bench(
+        "fx",
+        ParameterizedBenchmark::new("u64", |b, &s| b.iter(|| black_box(fxhash(s))), &U64_VALUES),
+    );
+    c.bench(
+        "fx",
+        ParameterizedBenchmark::new("u128", |b, &s| b.iter(|| black_box(fxhash(s))), &U128_VALUES),
+    );
+    c.bench(
+        "fx",
+        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(fxhash(s))), gen_strings()),
+    );
+}
+
+fn bench_fnv(c: &mut Criterion) {
+    c.bench(
+        "fnv",
+        ParameterizedBenchmark::new("u8", |b, &s| b.iter(|| black_box(fnvhash(s))), &U8_VALUES),
+    );
+    c.bench(
+        "fnv",
+        ParameterizedBenchmark::new("u16", |b, &s| b.iter(|| black_box(fnvhash(s))), &U16_VALUES),
+    );
+    c.bench(
+        "fnv",
+        ParameterizedBenchmark::new("u32", |b, &s| b.iter(|| black_box(fnvhash(s))), &U32_VALUES),
+    );
+    c.bench(
+        "fnv",
+        ParameterizedBenchmark::new("u64", |b, &s| b.iter(|| black_box(fnvhash(s))), &U64_VALUES),
+    );
+    c.bench(
+        "fnv",
+        ParameterizedBenchmark::new("u128", |b, &s| b.iter(|| black_box(fnvhash(s))), &U128_VALUES),
+    );
+    c.bench(
+        "fnv",
+        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(fnvhash(s))), gen_strings()),
+    );
+}
+
+fn bench_sea(c: &mut Criterion) {
+    c.bench(
+        "sea",
+        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(seahash(s))), gen_strings()),
+    );
+}
+
+fn bench_sip(c: &mut Criterion) {
+    c.bench(
+        "sip",
+        ParameterizedBenchmark::new("u8", |b, &s| b.iter(|| black_box(siphash(s))), &U8_VALUES),
+    );
+    c.bench(
+        "sip",
+        ParameterizedBenchmark::new("u16", |b, &s| b.iter(|| black_box(siphash(s))), &U16_VALUES),
+    );
+    c.bench(
+        "sip",
+        ParameterizedBenchmark::new("u32", |b, &s| b.iter(|| black_box(siphash(s))), &U32_VALUES),
+    );
+    c.bench(
+        "sip",
+        ParameterizedBenchmark::new("u64", |b, &s| b.iter(|| black_box(siphash(s))), &U64_VALUES),
+    );
+    c.bench(
+        "sip",
+        ParameterizedBenchmark::new("u128", |b, &s| b.iter(|| black_box(siphash(s))), &U128_VALUES),
+    );
+    c.bench(
+        "sip",
+        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(siphash(s))), gen_strings()),
+    );
+}
+
+criterion_main!(benches);
+criterion_group!(
+    benches,
+    bench_ahash,
+    bench_fallback,
+    bench_fx,
+    bench_fnv,
+    bench_sea,
+    bench_sip
+);
diff --git a/tests/map_tests.rs b/tests/map_tests.rs
new file mode 100644
index 0000000..70e4a86
--- /dev/null
+++ b/tests/map_tests.rs
@@ -0,0 +1,204 @@
+use std::hash::{Hash, Hasher};
+
+use criterion::*;
+use fxhash::FxHasher;
+
+use ahash::{AHasher, CallHasher};
+
+fn gen_word_pairs() -> Vec<String> {
+    let words: Vec<_> = r#"
+a, ability, able, about, above, accept, according, account, across, act, action,
+activity, actually, add, address, administration, admit, adult, affect, after,
+again, against, age, agency, agent, ago, agree, agreement, ahead, air, all,
+allow, almost, alone, along, already, also, although, always, American, among,
+amount, analysis, and, animal, another, answer, any, anyone, anything, appear,
+apply, approach, area, argue, arm, around, arrive, art, article, artist, as,
+ask, assume, at, attack, attention, attorney, audience, author, authority,
+available, avoid, away, baby, back, bad, bag, ball, bank, bar, base, be, beat,
+beautiful, because, become, bed, before, begin, behavior, behind, believe,
+benefit, best, better, between, beyond, big, bill, billion, bit, black, blood,
+blue, board, body, book, born, both, box, boy, break, bring, brother, budget,
+build, building, business, but, buy, by, call, camera, campaign, can, cancer,
+candidate, capital, car, card, care, career, carry, case, catch, cause, cell,
+center, central, century, certain, certainly, chair, challenge, chance, change,
+character, charge, check, child, choice, choose, church, citizen, city, civil,
+claim, class, clear, clearly, close, coach, cold, collection, college, color,
+come, commercial, common, community, company, compare, computer, concern,
+condition, conference, Congress, consider, consumer, contain, continue, control,
+cost, could, country, couple, course, court, cover, create, crime, cultural,
+culture, cup, current, customer, cut, dark, data, daughter, day, dead, deal,
+death, debate, decade, decide, decision, deep, defense, degree, Democrat,
+democratic, describe, design, despite, detail, determine, develop, development,
+die, difference, different, difficult, dinner, direction, director, discover,
+discuss, discussion, disease, do, doctor, dog, door, down, draw, dream, drive,
+drop, drug, during, each, early, east, easy, eat, economic, economy, edge,
+education, effect, effort, eight, either, election, else, employee, end, energy,
+enjoy, enough, enter, entire, environment, environmental, especially, establish,
+even, evening, event, ever, every, everybody, everyone, everything, evidence,
+exactly, example, executive, exist, expect, experience, expert, explain, eye,
+face, fact, factor, fail, fall, family, far, fast, father, fear, federal, feel,
+feeling, few, field, fight, figure, fill, film, final, finally, financial, find,
+fine, finger, finish, fire, firm, first, fish, five, floor, fly, focus, follow,
+food, foot, for, force, foreign, forget, form, former, forward, four, free,
+friend, from, front, full, fund, future, game, garden, gas, general, generation,
+get, girl, give, glass, go, goal, good, government, great, green, ground, group,
+grow, growth, guess, gun, guy, hair, half, hand, hang, happen, happy, hard,
+have, he, head, health, hear, heart, heat, heavy, help, her, here, herself,
+high, him, himself, his, history, hit, hold, home, hope, hospital, hot, hotel,
+hour, house, how, however, huge, human, hundred, husband, I, idea, identify, if,
+image, imagine, impact, important, improve, in, include, including, increase,
+indeed, indicate, individual, industry, information, inside, instead,
+institution, interest, interesting, international, interview, into, investment,
+involve, issue, it, item, its, itself, job, join, just, keep, key, kid, kill,
+kind, kitchen, know, knowledge, land, language, large, last, late, later, laugh,
+law, lawyer, lay, lead, leader, learn, least, leave, left, leg, legal, less,
+let, letter, level, lie, life, light, like, likely, line, list, listen, little,
+live, local, long, look, lose, loss, lot, love, low, machine, magazine, main,
+maintain, major, majority, make, man, manage, management, manager, many, market,
+marriage, material, matter, may, maybe, me, mean, measure, media, medical, meet,
+meeting, member, memory, mention, message, method, middle, might, military,
+million, mind, minute, miss, mission, model, modern, moment, money, month, more,
+morning, most, mother, mouth, move, movement, movie, Mr, Mrs, much, music, must,
+my, myself, name, nation, national, natural, nature, near, nearly, necessary,
+need, network, never, new, news, newspaper, next, nice, night, no, none, nor,
+north, not, note, nothing, notice, now, n't, number, occur, of, off, offer,
+office, officer, official, often, oh, oil, ok, old, on, once, one, only, onto,
+open, operation, opportunity, option, or, order, organization, other, others,
+our, out, outside, over, own, owner, page, pain, painting, paper, parent, part,
+participant, particular, particularly, partner, party, pass, past, patient,
+pattern, pay, peace, people, per, perform, performance, perhaps, period, person,
+personal, phone, physical, pick, picture, piece, place, plan, plant, play,
+player, PM, point, police, policy, political, politics, poor, popular,
+population, position, positive, possible, power, practice, prepare, present,
+president, pressure, pretty, prevent, price, private, probably, problem,
+process, produce, product, production, professional, professor, program,
+project, property, protect, prove, provide, public, pull, purpose, push, put,
+quality, question, quickly, quite, race, radio, raise, range, rate, rather,
+reach, read, ready, real, reality, realize, really, reason, receive, recent,
+recently, recognize, record, red, reduce, reflect, region, relate, relationship,
+religious, remain, remember, remove, report, represent, Republican, require,
+research, resource, respond, response, responsibility, rest, result, return,
+reveal, rich, right, rise, risk, road, rock, role, room, rule, run, safe, same,
+save, say, scene, school, science, scientist, score, sea, season, seat, second,
+section, security, see, seek, seem, sell, send, senior, sense, series, serious,
+serve, service, set, seven, several, sex, sexual, shake, share, she, shoot,
+short, shot, should, shoulder, show, side, sign, significant, similar, simple,
+simply, since, sing, single, sister, sit, site, situation, six, size, skill,
+skin, small, smile, so, social, society, soldier, some, somebody, someone,
+something, sometimes, son, song, soon, sort, sound, source, south, southern,
+space, speak, special, specific, speech, spend, sport, spring, staff, stage,
+stand, standard, star, start, state, statement, station, stay, step, still,
+stock, stop, store, story, strategy, street, strong, structure, student, study,
+stuff, style, subject, success, successful, such, suddenly, suffer, suggest,
+summer, support, sure, surface, system, table, take, talk, task, tax, teach,
+teacher, team, technology, television, tell, ten, tend, term, test, than, thank,
+that, the, their, them, themselves, then, theory, there, these, they, thing,
+think, third, this, those, though, thought, thousand, threat, three, through,
+throughout, throw, thus, time, to, today, together, tonight, too, top, total,
+tough, toward, town, trade, traditional, training, travel, treat, treatment,
+tree, trial, trip, trouble, true, truth, try, turn, TV, two, type, under,
+understand, unit, until, up, upon, us, use, usually, value, various, very,
+victim, view, violence, visit, voice, vote, wait, walk, wall, want, war, watch,
+water, way, we, weapon, wear, week, weight, well, west, western, what, whatever,
+when, where, whether, which, while, white, who, whole, whom, whose, why, wide,
+wife, will, win, wind, window, wish, with, within, without, woman, wonder, word,
+work, worker, world, worry, would, write, writer, wrong, yard, yeah, year, yes,
+yet, you, young, your, yourself"#
+        .split(',')
+        .map(|word| word.trim())
+        .collect();
+
+    let mut word_pairs: Vec<_> = Vec::new();
+    for word in &words {
+        for other_word in &words {
+            word_pairs.push(word.to_string() + " " + other_word);
+        }
+    }
+    assert_eq!(1_000_000, word_pairs.len());
+    word_pairs
+}
+
+#[allow(unused)] // False positive
+fn test_hash_common_words<T: Hasher>(hasher: impl Fn() -> T) {
+    let word_pairs: Vec<_> = gen_word_pairs();
+    check_for_collisions(&hasher, &word_pairs, 32);
+}
+
+#[allow(unused)] // False positive
+fn check_for_collisions<T: Hasher, H: Hash>(hasher: &impl Fn() -> T, items: &[H], bucket_count: usize) {
+    let mut buckets = vec![0; bucket_count];
+    for item in items {
+        let value = hash(item, &hasher) as usize;
+        buckets[value % bucket_count] += 1;
+    }
+    let mean = items.len() / bucket_count;
+    let max = *buckets.iter().max().unwrap();
+    let min = *buckets.iter().min().unwrap();
+    assert!(
+        (min as f64) > (mean as f64) * 0.95,
+        "min: {}, max:{}, {:?}",
+        min,
+        max,
+        buckets
+    );
+    assert!(
+        (max as f64) < (mean as f64) * 1.05,
+        "min: {}, max:{}, {:?}",
+        min,
+        max,
+        buckets
+    );
+}
+
+#[allow(unused)] // False positive
+fn hash<T: Hasher>(b: &impl Hash, hasher: &dyn Fn() -> T) -> u64 {
+    let hasher = hasher();
+    b.get_hash(hasher)
+}
+
+#[test]
+fn test_bucket_distribution() {
+    let hasher = || AHasher::new_with_keys(123456789, 987654321);
+    test_hash_common_words(&hasher);
+    let sequence: Vec<_> = (0..320000).collect();
+    check_for_collisions(&hasher, &sequence, 32);
+    let sequence: Vec<_> = (0..2560000).collect();
+    check_for_collisions(&hasher, &sequence, 256);
+    let sequence: Vec<_> = (0..320000).map(|i| i * 1024).collect();
+    check_for_collisions(&hasher, &sequence, 32);
+    let sequence: Vec<_> = (0..2560000_u64).map(|i| i * 1024).collect();
+    check_for_collisions(&hasher, &sequence, 256);
+}
+
+fn ahash_vec<H: Hash>(b: &Vec<H>) -> u64 {
+    let mut total: u64 = 0;
+    for item in b {
+        let mut hasher = AHasher::new_with_keys(1234, 5678);
+        item.hash(&mut hasher);
+        total = total.wrapping_add(hasher.finish());
+    }
+    total
+}
+
+fn fxhash_vec<H: Hash>(b: &Vec<H>) -> u64 {
+    let mut total: u64 = 0;
+    for item in b {
+        let mut hasher = FxHasher::default();
+        item.hash(&mut hasher);
+        total = total.wrapping_add(hasher.finish());
+    }
+    total
+}
+
+fn bench_ahash_words(c: &mut Criterion) {
+    let words = gen_word_pairs();
+    c.bench_function("aes_words", |b| b.iter(|| black_box(ahash_vec(&words))));
+}
+
+fn bench_fx_words(c: &mut Criterion) {
+    let words = gen_word_pairs();
+    c.bench_function("fx_words", |b| b.iter(|| black_box(fxhash_vec(&words))));
+}
+
+criterion_main!(benches);
+criterion_group!(benches, bench_ahash_words, bench_fx_words,);
diff --git a/tests/nopanic.rs b/tests/nopanic.rs
new file mode 100644
index 0000000..884f118
--- /dev/null
+++ b/tests/nopanic.rs
@@ -0,0 +1,54 @@
+use ahash::{AHasher, CallHasher, RandomState};
+use std::hash::BuildHasher;
+
+#[macro_use]
+extern crate no_panic;
+
+#[inline(never)]
+#[no_panic]
+fn hash_test_final(num: i32, string: &str) -> (u64, u64) {
+    use core::hash::Hasher;
+    let mut hasher1 = AHasher::new_with_keys(1, 2);
+    let mut hasher2 = AHasher::new_with_keys(3, 4);
+    hasher1.write_i32(num);
+    hasher2.write(string.as_bytes());
+    (hasher1.finish(), hasher2.finish())
+}
+
+#[inline(never)]
+fn hash_test_final_wrapper(num: i32, string: &str) {
+    hash_test_final(num, string);
+}
+
+#[inline(never)]
+#[no_panic]
+fn hash_test_specialize(num: i32, string: &str) -> (u64, u64) {
+    let hasher1 = AHasher::new_with_keys(1, 2);
+    let hasher2 = AHasher::new_with_keys(1, 2);
+    (num.get_hash(hasher1), string.as_bytes().get_hash(hasher2))
+}
+
+#[inline(never)]
+fn hash_test_random_wrapper(num: i32, string: &str) {
+    hash_test_specialize(num, string);
+}
+
+#[inline(never)]
+#[no_panic]
+fn hash_test_random(num: i32, string: &str) -> (u64, u64) {
+    let hasher1 = RandomState::with_seeds(1, 2, 3, 4).build_hasher();
+    let hasher2 = RandomState::with_seeds(1, 2, 3, 4).build_hasher();
+    (num.get_hash(hasher1), string.as_bytes().get_hash(hasher2))
+}
+
+#[inline(never)]
+fn hash_test_specialize_wrapper(num: i32, string: &str) {
+    hash_test_specialize(num, string);
+}
+
+#[test]
+fn test_no_panic() {
+    hash_test_final_wrapper(2, "Foo");
+    hash_test_specialize_wrapper(2, "Bar");
+    hash_test_random_wrapper(2, "Baz");
+}