My working unpac repository

Use standard hash function for `Z.hash` and add `Z.seeded_hash`

For consistency with other integer types in the standard library
(modules Int, Int32, Int64, Nativeint), let's use the standard
hash function (`Hashtbl.hash`) for `Z.hash` instead of our variant.

This is a bit slower but has several benefits (see #145):
- 32/64 bit compatibility
- better mixing of the bits of the result.

While we're at it, add a `Z.seeded_hash` function, defined as
`Hashtbl.seeded_hash`, so that the `Z` module can be used as the argument
to the `Hashtbl.MakeSeeded` functor.

+25 -11
-5
caml_z.c
··· 3350 3350 return acc; 3351 3351 } 3352 3352 3353 - CAMLprim value ml_z_hash(value v) 3354 - { 3355 - return Val_long(ml_z_custom_hash(v)); 3356 - } 3357 - 3358 3353 /* serialized format: 3359 3354 - 1-byte sign (1 for negative, 0 for positive) 3360 3355 - 4-byte size in bytes
+2 -1
z.ml
··· 258 258 external perfect_square: t -> bool = "ml_z_perfect_square" 259 259 external probab_prime: t -> int -> int = "ml_z_probab_prime" 260 260 external nextprime: t -> t = "ml_z_nextprime" 261 - external hash: t -> int = "ml_z_hash" [@@noalloc] 261 + let hash: t -> int = Stdlib.Hashtbl.hash 262 + let seeded_hash: int -> t -> int = Stdlib.Hashtbl.seeded_hash 262 263 external to_bits: t -> string = "ml_z_to_bits" 263 264 external of_bits: string -> t = "ml_z_of_bits" 264 265
+23 -5
z.mli
··· 486 486 @since 1.4 487 487 *) 488 488 489 - external hash: t -> int = "ml_z_hash" [@@noalloc] 489 + val hash: t -> int 490 490 (** Hashes a number, producing a small integer. 491 - The result is consistent with equality: if [a] = [b], then [hash a] = 492 - [hash b]. 493 - OCaml's generic hash function, [Hashtbl.hash], works correctly with 494 - numbers, but {!Z.hash} is slightly faster. 491 + The result is consistent with equality: 492 + if [a] = [b], then [hash a] = [hash b]. 493 + The result is the same as produced by OCaml's generic hash function, 494 + {!Hashtbl.hash}. 495 + Together with type {!Z.t}, the function {!Z.hash} makes it possible 496 + to pass module {!Z} as argument to the functor {!Hashtbl.Make}. 497 + @before 1.14 a different hash algorithm was used. 498 + *) 499 + 500 + val seeded_hash: int -> t -> int 501 + (** Like {!Z.hash}, but takes a seed as extra argument for diversification. 502 + The result is the same as produced by OCaml's generic seeded hash function, 503 + {!Hashtbl.seeded_hash}. 504 + Together with type {!Z.t}, the function {!Z.hash} makes it possible 505 + to pass module {!Z} as argument to the functor {!Hashtbl.MakeSeeded}. 506 + @since 1.14 495 507 *) 496 508 497 509 (** {1 Elementary number theory} *) ··· 717 729 Random numbers produced by this function are not cryptographically 718 730 strong and must not be used in cryptographic or high-security 719 731 contexts. See {!Z.random_int_gen} for an alternative. 732 + 733 + @since 1.13 720 734 *) 721 735 722 736 val random_bits: ?rng: Random.State.t -> int -> t ··· 731 745 Random numbers produced by this function are not cryptographically 732 746 strong and must not be used in cryptographic or high-security 733 747 contexts. See {!Z.random_bits_gen} for an alternative. 748 + 749 + @since 1.13 734 750 *) 735 751 736 752 val random_int_gen: fill: (bytes -> int -> int -> unit) -> t -> t ··· 751 767 << 752 768 Z.random_int_gen ~fill:Cryptokit.Random.secure_rng#bytes bound 753 769 >> 770 + @since 1.13 754 771 *) 755 772 756 773 val random_bits_gen: fill: (bytes -> int -> int -> unit) -> int -> t ··· 759 776 This is a more efficient special case of {!Z.random_int_gen} when the 760 777 bound is a power of two. The [fill] parameter is as described in 761 778 {!Z.random_int_gen}. 779 + @since 1.13 762 780 *) 763 781 764 782 (** {1 Prefix and infix operators} *)