From 4a4f2c30aef1b974385f0f170a0afb2a04628954 Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Tue, 25 Apr 2017 17:47:05 +0200 Subject: [PATCH] 2017-04-25 17:45 UTC+0200 Aleksander Czajczynski (hb fki.pl) * src/harbour.def ! add hb_rand*() functions, fixing hbtip regression (#154) after 1938dd0a7094ddf0cd3cdcb2ef9954afe99f969d ; import of 2014-12-10 14:38 UTC+0100 functions from Viktor's 3.4 fork * src/rtl/hbrand.c ! hb_randStr(): fixed possible GPF and other errors when passing negative size * include/harbour.hbx * include/hbapi.h * src/rtl/hbrandom.c + added C level hb_random_num_secure() which works like hb_random_num() but uses arc4 internally + added hb_randInt() which works the same as hb_RandomInt() but uses arc4 internally + added hb_randNum() which works the same as hb_Random() but uses arc4 internally --- ChangeLog.txt | 20 +++++++++++++++++ include/harbour.hbx | 2 ++ include/hbapi.h | 1 + src/harbour.def | 3 +++ src/rtl/hbrand.c | 18 ++++++++++----- src/rtl/hbrandom.c | 55 +++++++++++++++++++++++++++------------------ 6 files changed, 71 insertions(+), 28 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 32ca12632f..453ffbc7e5 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -10,6 +10,26 @@ * Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment */ +2017-04-25 17:45 UTC+0200 Aleksander Czajczynski (hb fki.pl) + * src/harbour.def + ! add hb_rand*() functions, fixing hbtip regression (#154) after + 1938dd0a7094ddf0cd3cdcb2ef9954afe99f969d + + ; import of 2014-12-10 14:38 UTC+0100 functions from Viktor's 3.4 fork + * src/rtl/hbrand.c + ! hb_randStr(): fixed possible GPF and other errors when passing + negative size + + * include/harbour.hbx + * include/hbapi.h + * src/rtl/hbrandom.c + + added C level hb_random_num_secure() which works like hb_random_num() + but uses arc4 internally + + added hb_randInt() which works the same as hb_RandomInt() but uses + arc4 internally + + added hb_randNum() which works the same as hb_Random() but uses + arc4 internally + 2017-04-25 15:59 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * include/hbexprb.c ! added missing code to restore original expression type after diff --git a/include/harbour.hbx b/include/harbour.hbx index ce4a42b987..de13da958b 100644 --- a/include/harbour.hbx +++ b/include/harbour.hbx @@ -749,6 +749,8 @@ DYNAMIC hb_ps DYNAMIC hb_PValue DYNAMIC hb_PWrite DYNAMIC hb_rand32 +DYNAMIC hb_randInt +DYNAMIC hb_randNum DYNAMIC hb_Random DYNAMIC hb_RandomInt DYNAMIC hb_RandomIntMax diff --git a/include/hbapi.h b/include/hbapi.h index 9f72fdf692..d21e3f00d5 100644 --- a/include/hbapi.h +++ b/include/hbapi.h @@ -998,6 +998,7 @@ extern HB_EXPORT double hb_numRound( double dResult, int iDec ); /* round a n extern HB_EXPORT double hb_numInt( double dNum ); /* take the integer part of the number */ extern HB_EXPORT void hb_random_seed( HB_I32 seed ); extern HB_EXPORT double hb_random_num( void ); +extern HB_EXPORT double hb_random_num_secure( void ); extern HB_EXPORT void hb_random_block( void * data, HB_SIZE len ); extern HB_EXPORT double hb_numDecConv( double dNum, int iDec ); extern HB_EXPORT double hb_numExpConv( double dNum, int iDec ); diff --git a/src/harbour.def b/src/harbour.def index 2e58b6a01d..40401f3849 100644 --- a/src/harbour.def +++ b/src/harbour.def @@ -934,6 +934,8 @@ HB_FUN_HB_PS HB_FUN_HB_PVALUE HB_FUN_HB_PWRITE HB_FUN_HB_RAND32 +HB_FUN_HB_RANDINT +HB_FUN_HB_RANDNUM HB_FUN_HB_RANDOM HB_FUN_HB_RANDOMINT HB_FUN_HB_RANDOMINTMAX @@ -3038,6 +3040,7 @@ hb_put_ieee754 hb_put_ord_ieee754 hb_random_block hb_random_num +hb_random_num_secure hb_random_seed hb_rddAllocWorkAreaAlias hb_rddCloseAll diff --git a/src/rtl/hbrand.c b/src/rtl/hbrand.c index 52a72a261f..5ba6ce3ff1 100644 --- a/src/rtl/hbrand.c +++ b/src/rtl/hbrand.c @@ -48,19 +48,25 @@ #include "arc4.h" -HB_FUNC( HB_RAND32 ) /* returns an integer between 0 and 0xFFFFFFFF (inclusive) */ -{ - hb_retnint( hb_arc4random() ); -} - void hb_random_block( void * data, HB_SIZE len ) { hb_arc4random_buf( data, len ); } +/* Returns a double value between 0 and 1 */ +double hb_random_num_secure( void ) +{ + return ( double ) hb_arc4random() / HB_U32_MAX; +} + +HB_FUNC( HB_RAND32 ) /* returns an integer between 0 and 0xFFFFFFFF (inclusive) */ +{ + hb_retnint( hb_arc4random() ); +} + HB_FUNC( HB_RANDSTR ) { - HB_SIZE len = hb_parns( 1 ); + HB_ISIZ len = hb_parns( 1 ); if( len > 0 ) { diff --git a/src/rtl/hbrandom.c b/src/rtl/hbrandom.c index 8a880accbd..6a81dfa82d 100644 --- a/src/rtl/hbrandom.c +++ b/src/rtl/hbrandom.c @@ -50,11 +50,10 @@ #include "hbstack.h" /* NOTE: core random generator algorithm is the work of Steve Park - http://www.cs.wm.edu/~va/software/park/ - */ + https://web.archive.org/web/www.cs.wm.edu/~va/software/park/ */ -#define MODULUS 2147483647 /* DON'T CHANGE THIS VALUE */ -#define MULTIPLIER 48271 /* DON'T CHANGE THIS VALUE */ +#define MODULUS 2147483647 /* DON'T CHANGE THIS VALUE */ +#define MULTIPLIER 48271 /* DON'T CHANGE THIS VALUE */ static HB_TSD_NEW( s_seed, sizeof( HB_I32 ), NULL, NULL ); #define SEED_PTR ( ( HB_I32 * ) hb_stackGetTSD( &s_seed ) ) @@ -93,17 +92,8 @@ void hb_random_seed( HB_I32 seed ) * SEED_PTR = ( seed < 0 ) ? seed + MODULUS : seed; } -/* - * hb_Random - * - * hb_Random() --> returns a real value n so that 0 <= n < 1 - * hb_Random( x ) --> returns a real number n so that 0 <= n < x - * hb_Random( x, y ) --> Returns a real number n so that x <= n < y - */ -HB_FUNC( HB_RANDOM ) +static void hb_random( double dRnd ) { - double dRnd = hb_random_num(); - if( ! HB_ISNUM( 1 ) ) hb_retnd( dRnd ); else if( ! HB_ISNUM( 2 ) ) @@ -123,17 +113,22 @@ HB_FUNC( HB_RANDOM ) } /* - * hb_RandomInt - * - * hb_RandomInt() --> returns 0 or 1, evenly distributed - * hb_RandomInt( N ) --> returns an integer between 1 and N (inclusive) - * hb_RandomInt( x, y ) --> Returns an integer number between x and y (inclusive) - * The integer returned is of the longest type available + * hb_Random() --> returns a real value n so that 0 <= n < 1 + * hb_Random( x ) --> returns a real number n so that 0 <= n < x + * hb_Random( x, y ) --> Returns a real number n so that x <= n < y */ -HB_FUNC( HB_RANDOMINT ) +HB_FUNC( HB_RANDOM ) { - double dRnd = hb_random_num(); + hb_random( hb_random_num() ); +} +HB_FUNC( HB_RANDNUM ) +{ + hb_random( hb_random_num_secure() ); +} + +static void hb_randomint( double dRnd ) +{ if( ! HB_ISNUM( 1 ) ) hb_retni( dRnd >= 0.5 ? 0 : 1 ); else if( ! HB_ISNUM( 2 ) ) @@ -152,6 +147,22 @@ HB_FUNC( HB_RANDOMINT ) } } +/* + * hb_RandomInt() --> returns 0 or 1, evenly distributed + * hb_RandomInt( N ) --> returns an integer between 1 and N (inclusive) + * hb_RandomInt( x, y ) --> Returns an integer number between x and y (inclusive) + * The integer returned is of the longest type available + */ +HB_FUNC( HB_RANDOMINT ) +{ + hb_randomint( hb_random_num() ); +} + +HB_FUNC( HB_RANDINT ) +{ + hb_randomint( hb_random_num_secure() ); +} + HB_FUNC( HB_RANDOMSEED ) { hb_random_seed( hb_parni( 1 ) );