Solved

Randomization function

Posted on 1998-10-06
28
499 Views
Last Modified: 2010-04-06
I need a function work like Random... not Random exactly but work like it : generate a pseudo-random numbers which depend on a random seed ( It must be reliable dependancy on that random-seed ).

Of cource I need the source of that function.

Thanks for advance
Motaz from Sudan.
motaz1@yahoo.com
0
Comment
Question by:Motaz
  • 7
  • 5
  • 5
  • +7
28 Comments
 
LVL 27

Expert Comment

by:kretzschmar
Comment Utility
try this

function RandomNumber(Seed : Longint) : LongInt;
begin
  randseed := seed;
  Randomnumber := random(1000);
end;

do you mean this?

meikl
0
 
LVL 7

Author Comment

by:Motaz
Comment Utility
No I don't want to use Random function at all, I want to make my own one.

Thanks
0
 
LVL 4

Expert Comment

by:erajoj
Comment Utility
Hi,
What kind of distribution do you want? Gaussian? Poisson?
Float? Integer? Slow? Fast? Accuracy?

I.e., what do you want it for?

/// John
0
 
LVL 7

Author Comment

by:Motaz
Comment Utility
Integer and fast
0
 
LVL 4

Expert Comment

by:erajoj
Comment Utility
Hi,
I still want to know what you want it for, so it can be adapted.
Don't you want any distribution accuracy?

/// John
0
 
LVL 8

Expert Comment

by:Answers2000
Comment Utility
When I wanted a fast random generator I used GetTickCount() and then mod it by some number to set the range.

This is not trully random, but was good enough provided called fairly infrequently
0
 
LVL 4

Expert Comment

by:erajoj
Comment Utility
Answers2000, that method is painfully slow, since you have to wait for the next tickcount before extracting a new pseudorandom number.

The GetTickCount function retrieves the number of milliseconds that have elapsed since the system was started. It is limited to the resolution of the system timer.

All ISA (IBM PC/AT and compatible) computer systems generate a hardware interrupt on IRQ0 18.2 Hz. This interrupt is mapped to INT 8 and can be intercepted by any application that wants to hook it. At 18.2 Hz, the interrupt occurs approximately once every 55 milliseconds. The Windows system driver hooks INT 8 and maintains the value returned by the GetTickCount function. Thus, this value is accurate only to within 55 milliseconds.

18.2 pseudorandom numbers/second isn't very fast, is it?
What "fast" means to me is >1MS/s.

/// John
0
 
LVL 8

Expert Comment

by:Answers2000
Comment Utility
erajoj -

1. no offsense intended by your comment is plain wrong (re:speed of GetTickCount)

Try this program (C++ as I prefer that)

#include <windows.h>
#include <stdio.h>

int main( int argc, char *argv[] )
{
      DWORD dwStart = GetTickCount() ;

      for ( int x = 0 ; x < 100000 ; x++ )
      {
            DWORD dw = GetTickCount() ;
      }

      DWORD dwEnd = GetTickCount() ;

      printf( "100000 retrieves of GetTickCount took %u milliseconds", (unsigned)(dwEnd-dwStart) ) ;

      return 0;
}

On my system 100,000 retrieves of GetTickCount took 15 milliseconds.  

GetTickCount returns (nearly) instantly.  It doesn't wait for another tick to occur.

Ignoring overhead of the loop

015 seconds to 10^5 iterations

is  0.00000015 seconds per iteration

which is  0.00015 Milliseconds per iteration


2. no offsense intended by your comment is plain wrong (re:resolution).

This demonstrates it:

#include <windows.h>
#include <stdio.h>

int main( int argc, char *argv[] )
{
      DWORD dwStart = GetTickCount() ;
      DWORD dwX[100000] ;

      for ( int x = 0 ; x < 100000 ; x++ )
      {
            dwX[x] = GetTickCount() ;
      }

      DWORD dwEnd = GetTickCount() ;

      printf( "100000 retrieves of GetTickCount took %u milliseconds\n", (unsigned)(dwEnd-dwStart) ) ;

      for ( int y = 0 ; y < 100 ; y++ )
      {
            printf( "%09u ", y, (unsigned)dwX[y] ) ;
      }

      printf( "\n" ) ;

      return 0;
}

Output is

100000 retrieves of GetTickCount took 9 milliseconds
000000000 000000001 000000002 000000003 000000004 000000005 000000006 000000007
000000008 000000009 000000010 000000011 000000012 000000013 000000014 000000015
000000016 000000017 000000018 000000019 000000020 000000021 000000022 000000023
000000024 000000025 000000026 000000027 000000028 000000029 000000030 000000031
000000032 000000033 000000034 000000035 000000036 000000037 000000038 000000039
000000040 000000041 000000042 000000043 000000044 000000045 000000046 000000047
000000048 000000049 000000050 000000051 000000052 000000053 000000054 000000055
000000056 000000057 000000058 000000059 000000060 000000061 000000062 000000063
000000064 000000065 000000066 000000067 000000068 000000069 000000070 000000071
000000072 000000073 000000074 000000075 000000076 000000077 000000078 000000079
000000080 000000081 000000082 000000083 000000084 000000085 000000086 000000087
000000088 000000089 000000090 000000091 000000092 000000093 000000094 000000095
000000096 000000097 000000098 000000099
Press any key to continue





0
 
LVL 8

Expert Comment

by:Answers2000
Comment Utility
eraroj -

A. Oops, sorry, typo in my program means you are right on #2 (but not #1)

printf( "%09u ", y, (unsigned)dwX[y] ) ;

should be

printf( "%09u ", (unsigned)dwX[y] ) ;

-- severe embarassment and red face


B. Having said that the Q'er didn't say he wanted fast.  A tick count is reasonable seed value for some other random number generator
0
 
LVL 4

Expert Comment

by:erajoj
Comment Utility
Hi,
No offence taken, since you don't seem to understand my comment.
"since you have to wait for the next tickcount" doesn't mean the function locks execution by that several subsequent values are equal.

And, could you tell me what "printf( "%09u ", y, (unsigned)dwX[y] ) ;" does?
Shouldn't it be "printf( "%04u %09u ", y, (unsigned)dwX[y] ) ;", or similar?

/// John
0
 
LVL 1

Expert Comment

by:BlackDeath
Comment Utility
hi, john!

it's always a pleasure to meet you.

Black Death.
0
 
LVL 4

Expert Comment

by:erajoj
Comment Utility
I wish it was mutual! ;-)))

/// John
0
 
LVL 1

Expert Comment

by:BlackDeath
Comment Utility
...here lie my sad remains...sniff!

;-)))))))

Black Death.
0
 
LVL 1

Expert Comment

by:Greedy
Comment Utility
Well I got one for you ... it's in C ... converted from Fortran :) but it's good.  I was going to post it here but it's has alot of documentation makeing it longer than one of these comments should be...but go look at it they have lots of nice stuff there too.  If you need help converting the C to Delphi just ask.

http://www.neutralzone.org/home/faqsys/

http://www.neutralzone.org/home/faqsys/docs/random.c

0
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 10

Expert Comment

by:viktornet
Comment Utility
Hello all!

I convert the random generator from the C code on that page and here it is in Delphi... I didn't take much time to take a closer look so there might be some mistakes... Please someone who has got some free time and knows C try to see if I've made any mistakes in the code.. Thanks you.... Here is the code....
---------------------------------
var
  u : array[0..97] of double;
  c, cd, cm : double;
  i97, j97 : integer;
  test : boolean = FALSE;
procedure rmarin(ij,kl : integer);
var
  i, j, k, l, ii, jj, m : integer;
  s, t : double;
begin
  if ((ij < 0) or (ij > 31328) or (kl < 0) or (kl > 30081)) then begin
    ShowMessage('The first random number seed must have a value between 0 and 31328.');
    ShowMessage('The second seed must have a value between 0 and 30081.');
    exit;
  end;
  i := (ij div 177) mod 177 + 2;
  j := ij mod 177 + 2;
  k := (kl div 169) mod 178 + 1;
  l := kl mod 169;        
  for ii := 0 to 97 do begin
    s := 0.0;
    t := 0.5;
    for jj := 1 to 24 do begin
      m := (((i*j) mod 179)*k) mod 179;
      i := j;
      j := k;
      k := m;
      l := (53*l + 1) mod 169;
      if ((l*m) mod 64 >= 32) then
        s := s + t;
      t := t * 0.5;
    end;
    u[ii] := s;
  end;
  c := 362436.0 / 16777216.0;
  cd := 7654321.0 / 16777216.0;
  cm := 16777213.0 / 16777216.0;
  i97 := 97;
  j97 := 33;        
  test := TRUE;
end;

procedure ranmar(rvec : array of double; len : Integer);
var
  ivec : integer;
  uni : double;
begin        
  if (test = FALSE) then begin
    ShowMessage('Call the init routine rmarin() before calling ranmar().');
    exit;
  end;
  for ivec := 1 to len do begin
    uni := u[i97] - u[j97];
    if (uni < 0.0) then
      uni := uni + 1.0;
    u[i97] := uni;
    Dec(i97);
    if (i97=0)then
      i97 := 97;
    Dec(j97);
    if (j97=0)then
      j97 := 97;
    c := c - cd;
    if (c < 0.0)then
      c := c + cm;
    uni := uni - c;
    if (uni<0.0)then
      uni := uni + 1.0;
    rvec[ivec] := uni;
  end;
end;

{This is actually the main() function in C code...}

procedure TForm1.Button1Click(Sender: TObject);
var
  temp : array[0..100] of double;
  ij, kl, len, i : integer;
begin
  ij := 1802;
  kl := 9373;
  rmarin(ij,kl);
  len := 100;
  for i := 0 to 200 do
    ranmar(temp, len);
  len := 6;
  ranmar(temp,len);
  for i := 1 to 6 do
    ShowMessage(Format('%12.1f ',[4096.0*4096.0*temp[i]]));
end;
--------------------
Regards,
Viktor Ivanov
0
 
LVL 8

Expert Comment

by:Answers2000
Comment Utility
eraroj -

>> And, could you tell me what "printf( "%09u ", y, (unsigned)dwX[y] ) ;" does?
>> Shouldn't it be "printf( "%04u %09u ", y, (unsigned)dwX[y] ) ;", or similar?

| As I said in previous comment
|
| printf( "%09u ", (unsigned)dwX[y] ) ;
|
|is what I meant
|
| -- this is to output array element y of array dwX as a 9 digit 0 preceded number

It's a mute point now, but I still think we were talking at cross purposes on the timer frequency issue (my point #1).  I won't hide my embarassment on my point #2 where I was plain wrong...

Anyway Greedy/Victor seem to have given an answer now.  So I'll leave this Q
0
 
LVL 5

Expert Comment

by:ronit051397
Comment Utility
Why don't you want to use the Random? Is that because you need to generate numbers that will "represent" another distribution, rather then the Uniform[0,1]?
0
 
LVL 7

Author Comment

by:Motaz
Comment Utility
I want to use a random for encryption, so that the important thing is random-seed.

If I get the code of Random function of pascal I'll be very thankful.

Motaz
0
 
LVL 10

Expert Comment

by:viktornet
Comment Utility
Hello MotaZ

There is the converted code of a C/C++ procedure for a random generator that Greedy pointed you to so you can give it a shot and see how it works,,,,

Regards,
Viktor Ivanov
0
 
LVL 7

Author Comment

by:Motaz
Comment Utility
I test it but it didn't work.

I want a simple pascal code.

Motaz
0
 
LVL 10

Expert Comment

by:viktornet
Comment Utility
Hey, maybe someone more experienced could try to fix something I've missed??? Talk to you later.. Bye...

Regards,
Viktor Ivanov
0
 
LVL 4

Expert Comment

by:erajoj
Comment Utility
Hi Motaz,
Since you don't seem to need a good random function,
here is an equivalent of Borlands Random/Randomize functions...

unit Rand;

interface

var
  RSeed: Integer = 0;

  function  RandInt( Range: Integer ): Integer;
  procedure RandomizeSeed;

implementation

const
  kernel = 'kernel32.dll';

procedure GetSystemTime; external kernel name 'GetSystemTime';

function RandInt( Range: Integer ): Integer; register; assembler;
asm
  IMUL EDX,RSeed,08088405H
  INC  EDX
  MOV  RSeed,EDX
  MUL  EDX
  MOV  EAX,EDX
end;

procedure RandomizeSeed; assembler;
var
  systime : record
    rgwDate : array [0..3] of Word;
    wHour   : Word;
    wMinute : Word;
    wSecond : Word;
    wMSec   : Word;
    res     : array [0..7] of Char;
  end;
asm
  LEA     EAX,systime
  PUSH    EAX
  CALL    GetSystemTime
  MOVZX   EAX,systime.wHour
  IMUL    EAX,60
  ADD     AX,systime.wMinute
  IMUL    EAX,60
  XOR     EDX,EDX
  MOV     DX,systime.wSecond
  ADD     EAX,EDX
  IMUL    EAX,1000
  MOV     DX,systime.wMSec
  ADD     EAX,EDX
  MOV     RSeed,EAX
end;

end.

This will give you exactly the same results as Random(...)/Randomize.
If you need help with the assembler, just ask!

/// John
0
 
LVL 5

Expert Comment

by:scrapdog
Comment Utility
Check out Robert Sedgewick's "Algorithms". Worth its weight in gold.
0
 
LVL 7

Author Comment

by:Motaz
Comment Utility
Thanks very mush John.

Motaz
0
 
LVL 10

Expert Comment

by:viktornet
Comment Utility
Sorry for the late comment, but
if you want to see how the real function of Delphi work then take a look at I think System.pas and you'll see the code there...

Regards,
Viktor Ivanov
0
 
LVL 4

Expert Comment

by:erajoj
Comment Utility
Yes Viktor, and in what great effect is that code different from the one I provided? :-)
Not everybody has access to the Delphi source, you know (only Pro & C/S ).
I provided a slightly altered, although blatanty similar, version since it is a copyright violation in distributing parts of the Delphi source.

/// John
0
 
LVL 10

Expert Comment

by:viktornet
Comment Utility
Hello John!

I didn't see the source I just know it's there so I post a comment. I don't know if yours is same as the one provided by Inprise or not!

Regards,
Viktor Ivanov
0
 
LVL 12

Accepted Solution

by:
rwilson032697 earned 40 total points
Comment Utility
I notice you say you want to use this for encryption.

You should look up the swag of encryption components on DSP. They often come with source and will include cryptographically secure hashes (random number generators) such as MD5 or SHA1. These are much better to use than a ad hoc method for generating random numbers. You might even find it useful just to use one of these encryption components.

Hope This helps,

Raymond.
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

Suggested Solutions

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

728 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now