diff options
author | Sverker Eriksson <[email protected]> | 2011-09-07 11:09:43 +0200 |
---|---|---|
committer | Sverker Eriksson <[email protected]> | 2011-09-07 11:09:43 +0200 |
commit | 02b8d9b4d669ae215b1c2423fa961db1b69a487f (patch) | |
tree | f7a1b27dc3a243da40dc2e98d888e6eb245e9342 /lib | |
parent | 22dae863060e0d66fa268f6d1cd4d6f084b850ab (diff) | |
download | otp-02b8d9b4d669ae215b1c2423fa961db1b69a487f.tar.gz otp-02b8d9b4d669ae215b1c2423fa961db1b69a487f.tar.bz2 otp-02b8d9b4d669ae215b1c2423fa961db1b69a487f.zip |
[crypto] Fix rand_uniform for negative values
Also let it throw badarg if 'Hi' is not larger than 'Lo'.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/crypto/doc/src/crypto.xml | 2 | ||||
-rw-r--r-- | lib/crypto/src/crypto.erl | 11 | ||||
-rw-r--r-- | lib/crypto/test/crypto_SUITE.erl | 11 |
3 files changed, 20 insertions, 4 deletions
diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml index 179ba4498c..96c4a072e1 100644 --- a/lib/crypto/doc/src/crypto.xml +++ b/lib/crypto/doc/src/crypto.xml @@ -744,7 +744,7 @@ Mpint() = <![CDATA[<<ByteLen:32/integer-big, Bytes:ByteLen/binary>>]]> <p>Generate a random number <c><![CDATA[N, Lo =< N < Hi.]]></c> Uses the <c>crypto</c> library pseudo-random number generator. The arguments (and result) can be either erlang integers or binary - multi-precision integers.</p> + multi-precision integers. <c>Hi</c> must be larger than <c>Lo</c>.</p> </desc> </func> <func> diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index c35dfcebab..c3e13d6b91 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -415,6 +415,13 @@ rand_uniform(From,To) when is_binary(From), is_binary(To) -> Whatever end; rand_uniform(From,To) when is_integer(From),is_integer(To) -> + if From < 0 -> + rand_uniform_pos(0, To - From) + From; + true -> + rand_uniform_pos(From, To) + end. + +rand_uniform_pos(From,To) when From < To -> BinFrom = mpint(From), BinTo = mpint(To), case rand_uniform(BinFrom, BinTo) of @@ -422,7 +429,9 @@ rand_uniform(From,To) when is_integer(From),is_integer(To) -> erlint(Result); Other -> Other - end. + end; +rand_uniform_pos(_,_) -> + error(badarg). rand_uniform_nif(_From,_To) -> ?nif_stub. diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl index 283aadb6ea..8d2f42469b 100644 --- a/lib/crypto/test/crypto_SUITE.erl +++ b/lib/crypto/test/crypto_SUITE.erl @@ -878,10 +878,17 @@ rand_uniform_aux_test(0) -> rand_uniform_aux_test(N) -> ?line L = N*1000, ?line H = N*100000+1, + ?line crypto_rand_uniform(L, H), + ?line crypto_rand_uniform(-L, L), + ?line crypto_rand_uniform(-H, -L), + ?line crypto_rand_uniform(-H, L), + ?line rand_uniform_aux_test(N-1). + +crypto_rand_uniform(L,H) -> ?line R1 = crypto:rand_uniform(L, H), ?line t(R1 >= L), - ?line t(R1 < H), - ?line rand_uniform_aux_test(N-1). + ?line t(R1 < H). + %% %% |