Random Numbers

General FreeBASIC programming questions.
albert
Posts: 6000
Joined: Sep 28, 2006 2:41
Location: California, USA

Random Numbers

Post by albert »

Could the FB Coders do something to the rnd function..

The rnd function if set to rnd*10000 will consistently pick numbers above 5000
I cant get it to select a full range of numbers. 90+% of the numbers will be above 5,000
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Random Numbers

Post by D.J.Peters »

Albert can you post your line with RND() I can't reproduce your result here.

Joshy

Code: Select all

dim as integer nLoops=1000000,nCount
for i as integer = 1 to nLoops
  if rnd()*10000>5000 then
    nCount+=1
  else
    nCount-=1
  end if
next
print "after " & nLoops & " loops nCount are " & nCount & " this are " & nCount/(abs(nLoops)/100) & " %"
sleep
albert
Posts: 6000
Joined: Sep 28, 2006 2:41
Location: California, USA

Re: Random Numbers

Post by albert »

@D.J.Peters

Code: Select all


dim as longint count = 0
dim as longint rand
for a as longint = 1 to 10000
    rand = int(rnd*100000)
    if  rand > 5000 then count+=1 
next

print "Picked " ; count ; " above 5,000"

sleep
end

sancho2
Posts: 547
Joined: May 17, 2015 6:41

Re: Random Numbers

Post by sancho2 »

I get 9514 out of 10000 that are above 5000
It seems there may be a problem.
Edit:
DJ Peters version however comes in at about %50. The difference is in the rnd * 10000 vs rnd * 100000, so probably no problem but a typo Albert.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Random Numbers

Post by D.J.Peters »

Yes albert needs new glasses to count zero's same as I ;-)

Code: Select all

dim as longint count = 0
dim as longint rand
for a as longint = 1 to 10000
    rand = int(rnd*10000)
    if  rand > 5000 then count+=1
next

print "Picked " ; count ; " above 5,000"
sleep
albert
Posts: 6000
Joined: Sep 28, 2006 2:41
Location: California, USA

Re: Random Numbers

Post by albert »

Heres a different counting
The mid and upper numbers are twice the lower value.

Code: Select all


dim as longint count(0 to 6)
dim as longint rand
for a as longint = 1 to 100000
    
    rand = int(rnd*100000)
    
    if  rand >    0 and rand <10000  then count(1)+=1
    if  rand >10000 and rand <20000  then count(2)+=1
    if  rand >20000 and rand <40000  then count(3)+=1
    if  rand >40000 and rand <60000  then count(4)+=1
    if  rand >60000 and rand <80000  then count(5)+=1
    if  rand >80000 and rand <100000 then count(6)+=1
    
next

print "Picked " ; count(1) ; " between    0   and  10,000"
print "Picked " ; count(2) ; " between 10,000 and  20,000"
print "Picked " ; count(3) ; " between 20,000 and  40,000"
print "Picked " ; count(4) ; " between 40,000 and  60,000"
print "Picked " ; count(5) ; " between 60,000 and  80,000"
print "Picked " ; count(6) ; " between 80,000 and 100,000"

sleep
end

caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: Random Numbers

Post by caseih »

Could be a platform-specific issue. You haven't said what platform you're using. Note that your code is not counting the values 0,10000,20000,40000,60000, or 80000. Also the first two divisions are half the width of the rest, so the count in those two is roughly half of the remaining divisions. Still, though, we're seeing pretty much even numbers cross the board here:

Code: Select all

Picked  9908 between    0   and  10,000
Picked  9936 between 10,000 and  20,000
Picked  20014 between 20,000 and  40,000
Picked  20115 between 40,000 and  60,000
Picked  20104 between 60,000 and  80,000
Picked  19918 between 80,000 and 100,000
I'm running Linux 64-bit here, and I know Linux provides some very good entropy.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Random Numbers

Post by D.J.Peters »

The range of random is pretty good and smooth.

Joshy

Code: Select all

 ' tera gen via RND() :lol:
const MAX_VALUE = 100000
const as single onestep = .2
dim as integer w,h,frames
dim as single x,y
screeninfo w,h : w*=.75 : h*=.75
screenres w,h
for i as integer=0 to 254
  palette i,i,i,i
next
x=w\2 : y=h\2
while inkey()=""
  dim as integer value = rnd()*MAX_VALUE
  dim as integer direction = value mod 8
  select case as const direction
  case 0 : x+=onestep
  case 1 : y+=onestep
  case 2 : x-=onestep
  case 3 : y-=onestep
  case 4 : x+=onestep : y+=onestep
  case 5 : x-=onestep : y-=onestep
  case 6 : x+=onestep : y-=onestep
  case 7 : x-=onestep : y+=onestep
  end select
  var c = point(x,y):if c<255 then c+=1
  pset (x,y),c
  frames+=1
  if frames mod 100=0 then sleep 10
wend
albert
Posts: 6000
Joined: Sep 28, 2006 2:41
Location: California, USA

Re: Random Numbers

Post by albert »

I'm using Windows 10 64 bit... on an AMD A8Vision 4 core 2GHz processor.

Set Message bytes to 1024 and garbage x to 128 then Generate a key and look at the numbers, they are all high values..

( After you type in the values in the message and garbage edits you have to "right click" on them to get them to set.)


Vari_Cyph_FB_V9

Code: Select all

#define WIN_INCLUDEALL
#Include once "windows.bi"
#Include once "/win/commctrl.bi"
#Include once "file.bi"

'===============================================================================
'===============================================================================
Dim shared as integer TabPages    : TabPages     = 1
Dim Shared as integer GarbageBits : GarbageBits  = 64
Dim Shared as integer GarbageBytes: GarbageBytes = 1
'===============================================================================
'===============================================================================
const Keys_Spinner_Val_max = 1024
const Keys_Spinner_val_min = 8
const Keys_Spinner_val_inc = 8 
dim shared as uinteger Keys_Spinner_val = 8
 
const Garbage_Spinner_Val_max = 128
const Garbage_Spinner_val_min = 1
const Garbage_Spinner_val_inc = 1
dim shared as uinteger Garbage_Spinner_val = 1 
'===============================================================================
'===============================================================================

dim shared as string file , extension , FileData

Redim shared as integer Key(0 to (64*TabPages)-1)
Redim shared as Ubyte SubKey(0 to 15)

for a as longint = lbound(key) to ubound(key)
    key(a) = a
next

Declare sub PrintKey()

Declare sub LoadCypheredText()
Declare sub Cypher()
Declare sub DeCypher()

Declare sub GetKeys()
Declare sub LoadKey()
Declare sub SaveKey()
Declare sub SaveOutput()

Declare sub GenerateKey()
Declare sub GenerateSubKey()
Declare sub CopyOutputToInput()

Declare sub MessageSpinner_Up()
Declare sub MessageSpinner_Dn()
Declare sub MessageSize()
Declare sub GarbageSpinner_Up()
Declare sub GarbageSpinner_Dn()
Declare sub GarbageSize()

Declare sub GetFileName()

ReDim shared as hwnd STATICS(1 to TabPages)
ReDim shared as hwnd EDIT_KEY(1 to TabPages,1 to 8,1 to 8)

Dim as string Help_Text
    Help_Text = "This encoder is a bit scrambler." + chr(13) + chr(10)
    Help_Text+= chr(13)+chr(10)
    Help_Text+= "It scrambles message bytes amongst several times as many garbage bytes." + chr(13) + chr(10)
    Help_Text+= "You select the number of message bytes. (top up/dn control) multiples of 8" + chr(13) + chr(10)
    Help_Text+= "Then" + chr(13) + chr(10)
    Help_Text+= "You select the number of garbage bytes as a multiple of message bytes 1x , 2x , 4x etc.." + chr(13) + chr(10)
    Help_Text+= "If garbage is set to 4 then the output will be 4 times as long as the message bytes." + chr(13)+chr(10) 
    Help_Text+= chr(13)+chr(10)
    Help_Text+= "If message bytes is set to 16 then the message is broken into chunks of 16 bytes." + chr(13) + chr(10)
    Help_Text+= "Message blocks can be any multiple of 8 , up to 1024."+chr(13)+chr(10)
    Help_Text+= "Garbage blocks can be any multiple of MessageBlocks up to 128."+chr(13)+chr(10)
    Help_Text+= chr(13)+chr(10)
    Help_Text+= "Type in the message or garbage size and right click the edit box to set it to that value." + chr(13)+chr(10)

Dim shared As MSG msg     ' Message variable (stores massages)
Dim shared As HWND hWnd _
                   , EDIT_IN _
                   , EDITKEY _
                   , STATIC_OUTS(0 to 15) _
                   , EDIT_OUTS(0 to 15) _
                   , EDIT_OUT _
                   , LOADCYPHTEXT_BTN _
                   , CYPHER_BTN _
                   , DECYPHER_BTN _
                   , LOADKEY_BTN _
                   , SAVEKEY_BTN _
                   , GENERATEKEY_BTN _
                   , label1 _
                   , SPINNER_MESSAGE_UP _
                   , SPINNER_MESSAGE_DN _
                   , MESSAGE_SIZE _
                   , label2 _
                   , SPINNER_GARBAGE_UP _
                   , SPINNER_GARBAGE_DN _
                   , GARBAGE_SIZE _
                   , HELP _
                   , GENERATESUBKEY_BTN _
                   , SAVEOUTPUT_BTN _
                   , COPY_OUTPUT_TO_INPUT 'for multiple cyphering.
'===============================================================================                   
' Create window
hWnd = CreateWindowEx( 0, "#32770", "Vari_Cyph_FB_V8 May/2015", WS_OVERLAPPEDWINDOW Or WS_VISIBLE, 100, 100, 600, 600, 0, 0, 0, 0 )

'create in edit
EDIT_IN  = CreateWindowEx( 0, "EDIT", "", WS_VISIBLE Or WS_CHILD Or WS_BORDER or ES_MULTILINE or WS_VSCROLL or WS_HSCROLL               , 10, 10,430,110, hWnd, 0, 0, 0 )

'create readonly edit out
EDIT_OUT = CreateWindowEx( 0, "EDIT", "", WS_VISIBLE Or WS_CHILD Or WS_BORDER or ES_MULTILINE or WS_VSCROLL or WS_HSCROLL or ES_READONLY, 10,430,430,130, hWnd, 0, 0, 0 )

'create key edit
EDITKEY = CreateWindowEx( 0, "EDIT", "", WS_VISIBLE Or WS_CHILD Or WS_BORDER or ES_MULTILINE or WS_VSCROLL or WS_HSCROLL or ES_READONLY, 10,125,430,215, hWnd, 0, 0, 0 )

'create labels and edits for output.
dim as integer count1
for y as integer = 1 to 2 step 1
    for x as integer = 1 to 8 step 1
       count1 = ((y*8)-8)+x-1
       SubKey(count1)=(65+count1)
       STATIC_OUTS(count1) = CreateWindowEx( 0,"STATIC", right("0000" + bin(count1),4), WS_VISIBLE Or WS_CHILD             ,(x*38)-38+(15*x) ,280+( (y*12)+20+(32*y)) , 38, 20, hWnd, 0, 0, 0 )
       EDIT_OUTS( count1 ) = CreateWindowEx( 0,"EDIT"  , CHR(SubKey(count1))          , WS_VISIBLE Or WS_CHILD Or WS_BORDER,(x*38)-30+(15*x) ,305+( (y*12)+10+(32*y)) , 18, 20, hWnd, 0, 0, 0 )
   next
next

LOADCYPHTEXT_BTN  = CreateWindowEx( 0,"BUTTON"  , "Load Cypher"  , WS_VISIBLE Or WS_CHILD Or WS_BORDER,460 ,10 , 100, 25, hWnd, 0, 0, 0 )
CYPHER_BTN        = CreateWindowEx( 0,"BUTTON"  , "Cypher"       , WS_VISIBLE Or WS_CHILD Or WS_BORDER,460 ,50 , 100, 25, hWnd, 0, 0, 0 )
DECYPHER_BTN      = CreateWindowEx( 0,"BUTTON"  , "DeCypher"     , WS_VISIBLE Or WS_CHILD Or WS_BORDER,460 ,90 , 100, 25, hWnd, 0, 0, 0 )

LOADKEY_BTN       = CreateWindowEx( 0,"BUTTON"  , "Load Key"     , WS_VISIBLE Or WS_CHILD Or WS_BORDER,460 ,140 , 100, 25, hWnd, 0, 0, 0 )
SAVEKEY_BTN       = CreateWindowEx( 0,"BUTTON"  , "Save Key"     , WS_VISIBLE Or WS_CHILD Or WS_BORDER,460 ,180 , 100, 25, hWnd, 0, 0, 0 )
GENERATEKEY_BTN   = CreateWindowEx( 0,"BUTTON"  , "Generate Key" , WS_VISIBLE Or WS_CHILD Or WS_BORDER,460 ,220 , 100, 25, hWnd, 0, 0, 0 )
GENERATESUBKEY_BTN= CreateWindowEx( 0,"BUTTON" ,"Generate SubKey", WS_VISIBLE Or WS_CHILD Or WS_BORDER,445 ,400 , 130, 25, hWnd, 0, 0, 0 )
SAVEOUTPUT_BTN    = CreateWindowEx( 0,"BUTTON" ,  "Save Output"  , WS_VISIBLE Or WS_CHILD Or WS_BORDER,445 ,450 , 130, 25, hWnd, 0, 0, 0 )
COPY_OUTPUT_TO_INPUT = CreateWindowEx( 0,"BUTTON" ,  "Copy to Input", WS_VISIBLE Or WS_CHILD Or WS_BORDER,445 ,500 , 130, 25, hWnd, 0, 0, 0 )

label1               = CreateWindowEx( 0,"EDIT"    , "Message Size"      , WS_VISIBLE or WS_CHILD or ES_READONLY ,460 ,250 , 100, 12, hWnd, 0, 0, 0 )   
SPINNER_MESSAGE_UP   = CreateWindowEx( 0,"BUTTON"  , "/\"                , WS_VISIBLE Or WS_CHILD Or WS_BORDER   ,543 ,270 ,  35, 12, hWnd, 0, 0, 0 )
SPINNER_MESSAGE_DN   = CreateWindowEx( 0,"BUTTON"  , "\/"                , WS_VISIBLE Or WS_CHILD Or WS_BORDER   ,543 ,283 ,  35, 12, hWnd, 0, 0, 0 )
MESSAGE_SIZE         = CreateWindowEx( 0,"EDIT"    , str(TabPages*8)     , WS_VISIBLE Or WS_CHILD Or WS_BORDER   ,460 ,270 ,  80, 25, hWnd, 0, 0, 0 )

label2               = CreateWindowEx( 0,"EDIT"    , "Garbage Size"      , WS_VISIBLE or WS_CHILD or ES_READONLY ,460 ,295 , 100, 12, hWnd, 0, 0, 0 )   
SPINNER_GARBAGE_UP   = CreateWindowEx( 0,"BUTTON"  , "/\"                , WS_VISIBLE Or WS_CHILD Or WS_BORDER   ,543 ,315 ,  35, 12, hWnd, 0, 0, 0 )
SPINNER_GARBAGE_DN   = CreateWindowEx( 0,"BUTTON"  , "\/"                , WS_VISIBLE Or WS_CHILD Or WS_BORDER   ,543 ,328 ,  35, 12, hWnd, 0, 0, 0 )
GARBAGE_SIZE         = CreateWindowEx( 0,"EDIT"    , str(GarbageBytes)   , WS_VISIBLE Or WS_CHILD Or WS_BORDER   ,460 ,315 ,  80, 25, hWnd, 0, 0, 0 )

HELP                 = CreateWindowEx( 0,"BUTTON"  , "Help"         , WS_VISIBLE Or WS_CHILD Or WS_BORDER,445 ,355 , 130, 25, hWnd, 0, 0, 0 )
'End Control setup

PrintKey()

'===============================================================================
'===============================================================================
'begin mesage processing
While GetMessage( @msg, 0, 0, 0 )
    
    TranslateMessage( @msg )
    DispatchMessage( @msg )
  
    Select Case msg.hwnd
        Case hWnd
            Select Case msg.message
                Case 273
                PostQuitMessage(0)
                'End
            End Select
            
        Case LOADCYPHTEXT_BTN
            Select Case msg.message
                case WM_LBUTTONDOWN
                    LoadCypheredText()
            End Select
        
        Case CYPHER_BTN
            Select Case msg.message
                case WM_LBUTTONDOWN
                    Cypher()
            End Select
        
        Case DECYPHER_BTN
            Select Case msg.message
                case WM_LBUTTONDOWN
                    DeCypher()
            End Select
        
        Case LOADKEY_BTN
            Select Case msg.message
                case WM_LBUTTONDOWN
                    LoadKey()
            End Select
        
        Case SAVEKEY_BTN
            Select Case msg.message
                case WM_LBUTTONDOWN
                    SaveKey()
            End Select
        
        case SPINNER_MESSAGE_UP
            select case msg.message
                case WM_LBUTTONDOWN
                    MessageSpinner_Up()
            end select

        case SPINNER_MESSAGE_DN
            select case msg.message
                case WM_LBUTTONDOWN
                    MessageSpinner_Dn()
            end select
        
        Case MESSAGE_SIZE
            select case msg.message
                case WM_RBUTTONDOWN
                    MessageSize()
            end select
            
        Case SPINNER_GARBAGE_UP
            select case msg.message
                case WM_LBUTTONDOWN
                    GarbageSpinner_Up()
            end select
        
        Case SPINNER_GARBAGE_DN
            select case msg.message
                case WM_LBUTTONDOWN
                    GarbageSpinner_Dn()
            end select
            
        Case GARBAGE_SIZE
            select case msg.message
                case WM_RBUTTONDOWN
                    GarbageSize()
            end select
        
        Case HELP
            select case msg.message
                case WM_LBUTTONDOWN
                    MessageBox(0,Help_Text,"Help",MB_OK)
            end select
            
        Case SAVEOUTPUT_BTN
            Select Case msg.message
                case WM_LBUTTONDOWN
                    SaveOutput()
            End Select
        
        Case COPY_OUTPUT_TO_INPUT
            select Case msg.message
                case WM_LBUTTONDOWN
                    CopyOutputToInput()
            end select
        
        Case GENERATEKEY_BTN
            Select Case msg.message
                case WM_LBUTTONDOWN
                    GenerateKey()
            End Select
        
        Case GENERATESUBKEY_BTN
            Select Case msg.message
                case WM_LBUTTONDOWN
                    GenerateSubKey()
            End Select
    
    End Select

Wend
PostQuitMessage(0)
END
'===============================================================================
'===============================================================================
'subs and functions below here
'===============================================================================
'===============================================================================
sub MessageSpinner_Up()
    if Keys_Spinner_val < Keys_Spinner_val_max then Keys_Spinner_val+= Keys_Spinner_val_inc
    SetWindowText(MESSAGE_SIZE,str(Keys_Spinner_val))
    TabPages = Keys_Spinner_val / 8
    Garbagebits = Garbage_Spinner_Val*8*Keys_Spinner_Val
    GarbageBytes = GarbageBits/8/Keys_Spinner_val
    Redim as integer Key(0 to (64*TabPages)-1)
    PrintKey()
end sub
'===============================================================================
'===============================================================================
sub MessageSpinner_Dn()
    if Keys_Spinner_val > Keys_Spinner_val_min then Keys_Spinner_val-= Keys_Spinner_val_inc
    SetWindowText(MESSAGE_SIZE,str(Keys_Spinner_val))
    TabPages = Keys_Spinner_val / 8
    Garbagebits = Garbage_Spinner_Val*8*Keys_Spinner_Val
    GarbageBytes = GarbageBits/8/Keys_Spinner_val
    Redim as integer Key(0 to (64*TabPages)-1)
    PrintKey()
end sub
'===============================================================================
'===============================================================================
sub MessageSize()
    dim as string*6 textin
    GetWindowText(MESSAGE_SIZE,textin,5)
    textin=trim(textin,chr(32))
    textin=trim(textin,chr(0))
    Keys_Spinner_val = val(textin)
    if Keys_Spinner_val > Keys_Spinner_Val_max = 1024 then 
        Keys_Spinner_val = Keys_Spinner_val_max
    end if
    dim as string str1
    dim as integer dec1
    do
        str1=str(Keys_Spinner_val/8)
        dec1=instr(1,str1,".")
        if dec1<>0 then Keys_Spinner_val+=1
    loop until dec1 = 0
    SetWindowText(MESSAGE_SIZE,str(Keys_Spinner_val))
    TabPages = Keys_Spinner_val / 8
    Garbagebits = Garbage_Spinner_Val*8*Keys_Spinner_Val
    GarbageBytes = GarbageBits/8/Keys_Spinner_val
    Redim as integer Key(0 to (64*TabPages)-1)
    PrintKey()
end sub
'===============================================================================
'===============================================================================
sub GarbageSpinner_Up()
    if Garbage_Spinner_val < Garbage_Spinner_val_max then Garbage_Spinner_val+= Garbage_Spinner_val_inc
    Garbagebits = Garbage_Spinner_Val*8*Keys_Spinner_Val
    GarbageBytes = GarbageBits/8/Keys_Spinner_val
    SetWindowText(GARBAGE_SIZE,str(Garbage_Spinner_val))
end sub
'===============================================================================
'===============================================================================
sub GarbageSpinner_Dn()
    if Garbage_Spinner_val > Garbage_Spinner_val_min then Garbage_Spinner_val-= Garbage_Spinner_val_inc
    Garbagebits = Garbage_Spinner_Val*8*Keys_Spinner_Val
    GarbageBytes = GarbageBits/8/Keys_Spinner_val
    SetWindowText(GARBAGE_SIZE,str(Garbage_Spinner_val))
End Sub
'===============================================================================
'===============================================================================
sub GarbageSize()
    dim as string*6 textin
    GetWindowText(GARBAGE_SIZE,textin,5)
    textin=trim(textin,chr(32))
    textin=trim(textin,chr(0))
    Garbage_Spinner_val = val(textin)
    if Garbage_Spinner_val > Garbage_Spinner_val_max then 
        Garbage_Spinner_val = Garbage_Spinner_val_max
    end if
    SetWindowText(GARBAGE_SIZE,str(Garbage_Spinner_val))
    TabPages = Keys_Spinner_val / 8
    Garbagebits = Garbage_Spinner_Val*8*Keys_Spinner_Val
    GarbageBytes = GarbageBits/8/Keys_Spinner_val
    Redim as integer Key(0 to (64*TabPages)-1)
    PrintKey()
end sub
'===============================================================================
'===============================================================================
sub PrintKey()
    dim as string KeyText
    dim as longint count = 1
    for a as longint = lbound(key) to ubound(Key)
        if a mod 8 = 0 then KeyText+=right("____" + str(count),4)+")"
        KeyText+=right("________"+str(key(a)),8)
        if a mod 8 = 7 then KeyText +=chr(13)+chr(10) : count+=1
    next
    SETWINDOWTEXT( EDITKEY , KeyText)
end sub
'===============================================================================
'===============================================================================
sub LoadCypheredText()
    
    GetFileName()
    FileData=""
    
    if fileexists(file) then 
        
        dim as ulongint position
        dim as ulongint length = filelen(file)-2
        dim as ubyte char
        
        open file for binary as #1
            
            position=0
            do
                Get #1,,Char
                FileData+=chr(char)
                position+=1
            loop until position=length
        
        close #1
        
        SetWindowText(EDIT_IN,FileData)
        
        FileData=""
        file=""
    end if
    
end sub

'===============================================================================
'===============================================================================
sub Cypher()
    
    'get message input from input edit_box into a string
    dim as string GetInputMessage
    dim as integer txtlen
    txtlen = (GetWindowTextLength(EDIT_IN)+1)
    GetInputMessage = string(txtlen,chr(0))
    GetWindowText(EDIT_IN , GetInputMessage, txtlen)
    GetInputMessage = trim(GetInputMessage,Chr(32))
    GetInputMessage = trim(GetInputMessage,chr(0))
    
    'make input string an even number of Block sizes
    dim as string str1
    dim as double dec
    do
        str1=str( len(GetInputMessage) / (TabPages*8) )
        dec=instr(1,str1,".")
        if dec<>0 then GetInputMessage+="_" 'if message is not a multiple of (TabPages*8) characters
    loop until dec=0
    
    'turn message into binary
    dim as string BinaryMessageBlocks
    for a as integer = 1 to len(GetInputMessage) step 1
        BinaryMessageBlocks+= right("00000000" + bin( asc(mid(GetInputMessage,a,1)) ) ,8)
    next    
    
    'stick user message bits (TabPages*64/TabPages) into random garbage of length GarbageBits
    dim as string MessageBits
    dim as string RandomGarbage
    dim as string Accumulated
    for a as integer = 1 to len(BinaryMessageBlocks) step (64*TabPages)
        
        MessageBits = mid(BinaryMessageBlocks,a, 64*tabPages)
        
        RandomGarbage=""
        for garbage as integer = 1 to GarbageBits step 1 
            RandomGarbage+=str( int(rnd*2) ) 'right("00000000" + bin(int(rnd*26)+97) , 8)
        next
        
        for insert as integer = lbound(Key) to ubound(Key)
            mid(RandomGarbage,Key(insert),1) = mid(MessageBits,insert+1,1)
        next
        Accumulated+=RandomGarbage
    next
    
    
    dim as string CypheredOutput
    dim as string*4 QuadBits
    for a as integer = 1 to len(Accumulated) step 4
        dec=0
        QuadBits=mid(Accumulated,a,4)
        mid(Accumulated,a,4)="0000"
        
        if mid(QuadBits,1,1)="1" then Dec+=8
        if mid(QuadBits,2,1)="1" then Dec+=4
        if mid(QuadBits,3,1)="1" then Dec+=2
        if mid(QuadBits,4,1)="1" then Dec+=1
        
        CypheredOutput+=Chr(SubKey(Dec))
    next
    
    SetWindowText(EDIT_OUT,CypheredOutput)
    CypheredOutput=""
    
end sub
'===============================================================================
'===============================================================================
sub DeCypher()
    
    'get message input from input edit_box into a string
    dim as string GetInputMessage
    dim as integer txtlen
    txtlen = (GetWindowTextLength(EDIT_IN)+1)
    GetInputMessage = string(txtlen,chr(0))
    GetWindowText(EDIT_IN , GetInputMessage, txtlen)
    GetInputMessage = trim(GetInputMessage,chr(0))
    
    if len(GetInputMessage)<>0 then
        
        dim as string BinarySubOutput(1 to (len(GetInputMessage)/(GarbageBits/8)/2) )
        dim as string Bites
        dim as integer Chunks = (len(GetInputMessage)/(GarbageBits/8)/2)
        dim as ubyte Char
        Dim as integer Dec=1
        for a as integer = 1 to len(GetInputMessage) step (len(GetInputMessage)/Chunks)
            Bites = mid( GetInputMessage, a, len(GetInputMessage)/Chunks )
            for b as integer = 1 to len(bites) 
                Char = asc( mid(Bites,b,1) )
                for c as integer = 0 to 15
                    if Char = SubKey(c) then BinarySubOutput(Dec)+=right("0000"+bin(c),4)
                next
            next
            Dec+=1
        next
        
        Dec-=1
        dim as string Binary_out
        for a as integer = 1 to Dec step 1
            for b as integer = 0 to ubound(Key)
                Binary_Out+= mid(BinarySubOutput(a),Key(b),1)
            next
        next
        
        dim as string FinalOutput
        dim as string*8 OctaBits
        for a as integer = 1 to len(Binary_Out) step 8
            OctaBits = mid(Binary_Out,a,8)
            mid(Binary_Out,a,8)="00000000"
            Dec=0
            if mid(OctaBits,1,1)="1" then Dec+=128
            if mid(OctaBits,2,1)="1" then Dec+= 64
            if mid(OctaBits,3,1)="1" then Dec+= 32
            if mid(OctaBits,4,1)="1" then Dec+= 16
            if mid(OctaBits,5,1)="1" then Dec+=  8
            if mid(OctaBits,6,1)="1" then Dec+=  4
            if mid(OctaBits,7,1)="1" then Dec+=  2
            if mid(OctaBits,8,1)="1" then Dec+=  1
        
            FinalOutput+=Chr(Dec)
        next
        
        FinalOutput = rtrim(FinalOutput,"_")
        SetWindowText(EDIT_OUT,FinalOutput)
    
    end if
    
end sub
'===============================================================================
'===============================================================================
sub LoadKey()
    
    GetFileName()
    
    if fileexists(file) then
        
        open file for input as #1
            
            dim as String Inputs
            
            line input #1 , Inputs
            SetWindowText(MESSAGE_SIZE,Inputs)
            Keys_Spinner_Val = val(inputs)
            MessageSize()
            
            line input #1 , Inputs
            SetWindowText(GARBAGE_SIZE,Inputs)
            Garbage_spinner_val = val(inputs)
            GarbageSize()
            
            Redim Key(0 to Keys_Spinner_val*8-1)
            Redim SubKey(0 to 15)

            dim as ulongint count
            
            count=0
            do
                line input #1 , Inputs
                Key(count) = val(Inputs)
                count+=1
            loop until count > ubound(Key)
            
            count=0
            do
                line input #1 , Inputs
                SubKey(count) = val(Inputs)
                count+=1
            loop until count = 16
            
        Close #1
        
        PrintKey()
        
        dim as integer dec
        for y as integer = 1 to 2 step 1
            for x as integer = 1 to 8 step 1
                Dec = (((y*8)-8)+x)-1
                'print y,x,Dec,SubKey(Dec)
                SetWindowText(EDIT_OUTS( Dec ) , chr(SubKey(Dec)) )
            next
        next
            
        file=""
        extension=""

    end if
    
end sub
'===============================================================================
'===============================================================================
sub SaveKey()
    
    GetFileName()
    
    dim as string SaveKeys = ""
    
    if file<>"" then
    
        open file for output as #1
            
            dim as string*6 textin
            GetWindowText(MESSAGE_SIZE,textin,5)
            print #1 , textin
            
            GetWindowText(GARBAGE_SIZE,textin,5)
            print #1 , textin
            
            for a as integer = lbound(key) to ubound(key)
                print #1 , str(Key(a))
            next
        
            for a as integer = 0 to 15
                Print #1 , SubKey(a)
            next
        
        close #1
    
    end if
    
end sub
'===============================================================================
'===============================================================================
sub SaveOutput()
    
    GetFileName()
    if file<>"" then 
        
        'get message input from Output edit_box into a string
        dim as string GetOutputMessage
        dim as integer txtlen
        txtlen = (GetWindowTextLength(EDIT_OUT)+1)
        GetOutputMessage = string(txtlen,chr(0))
        GetWindowText(EDIT_OUT , GetOutputMessage, txtlen)
        GetOutputMessage = trim(GetOutputMessage,chr(0))

        open file for output as #1
        
            print #1 , GetOutputMessage
        
        close #1
    
    end if
    
end sub
'===============================================================================
'===============================================================================
Sub CopyOutputToInput()
        'get message input from Output edit_box into a string
        dim as string GetOutputMessage
        dim as integer txtlen
        txtlen = (GetWindowTextLength(EDIT_OUT)+1)
        GetOutputMessage = string(txtlen,chr(0))
        GetWindowText(EDIT_OUT , GetOutputMessage, txtlen)
        GetOutputMessage = trim(GetOutputMessage,chr(0))
        SetWindowText(EDIT_IN , GetOutputMessage)
        SetWindowText(EDIT_OUT , "")
end sub
'===============================================================================
'===============================================================================
sub GenerateKey()
    ' ((a*64)-64)+((x*8)-8)+y
    Redim Key(0 to (TabPages*64-1) )
        
    dim a as integer
    dim b as integer
    dim c as integer
    dim d as integer
  
    'create random key for main cypher.
    for a = 0 to (TabPages*64)-1
        key(a) = 0
    next
      
    a=0
    do
        b = int(rnd*GarbageBits)+1
        randomize b / sin(rnd*timer) / tan(timer/1000)
        do
            b = int(rnd*GarbageBits)+1
            d = 0
            for c = 0 to a
               if key(c) = b then d = 1 
            next
        loop until d = 0
        key(a) = b
        a = a + 1      
    loop until a=(TabPages*64)      

    PrintKey()
        
end sub
'===============================================================================
'===============================================================================
sub GenerateSubKey()
      
    Redim SubKey(0 to 15)
    'create 16 letter subsitution for output
    dim a as integer
    dim b as integer
    dim c as integer
    dim d as integer
      
    for a = 0 to 15
        SubKey(a) = 0
    next
    a=0
    do
        b = int( rnd*26 )+65
        do
            b = int( rnd*26 )+65
            d = 0
            for c=0 to a
                if SubKey(c) = b then d = 1 
            next
        loop  until d = 0
        SubKey(a) = b
        a=a+1      
    loop until a=16      
      
    'answer = ((a*8)-8) +b
    for a = 1 to 2
        for b = 1 to 8
            'print ((a*8)-8) +b-1
            SetWindowText( EDIT_OUTS( ((a*8)-8)+b-1 ) , chr( SubKey( ((a*8)-8)+b-1 ) ) )
        next
    next
    
end sub

'===============================================================================
'===============================================================================
sub getfilename()
        dim ofn as OPENFILENAME
        dim filename as zstring * MAX_PATH+1
        
        with ofn
                .lStructSize            = sizeof( OPENFILENAME )
                .hwndOwner              = hWnd
                .hInstance              = GetModuleHandle( NULL )
                .lpstrFilter            = strptr( !"All Files, (*.*)\0*.*\0\0" )
                .lpstrCustomFilter      = NULL
                .nMaxCustFilter         = 0
                .nFilterIndex           = 1
                .lpstrFile              = @filename
                .nMaxFile               = sizeof( filename )
                .lpstrFileTitle         = NULL
                .nMaxFileTitle          = 0
                .lpstrInitialDir        = NULL
                .lpstrTitle             = @"File To Open."
                .Flags                  = OFN_EXPLORER 'or OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST
                .nFileOffset            = 0
                .nFileExtension         = 0
                .lpstrDefExt            = NULL
                .lCustData              = 0
                .lpfnHook               = NULL
                .lpTemplateName         = NULL
        end with
        
        if( GetOpenFileName( @ofn ) = FALSE ) then
            file = ""
            extension=""
            return
        else
            file = filename
            extension = right$(filename,4)
        end if

end sub

albert
Posts: 6000
Joined: Sep 28, 2006 2:41
Location: California, USA

Re: Random Numbers

Post by albert »

I found the problem its in the RANDOMIZE function ( Randomize timer )

Code: Select all


dim as longint count(1 to 10)
dim as longint rand
dim as longint size = 100000
for a as longint = 1 to 1000000
    
    randomize timer
    rand = int(rnd*size)
    
    if  rand >     0 and rand < 10000 then count( 1)+=1
    if  rand > 10000 and rand < 20000 then count( 2)+=1
    if  rand > 20000 and rand < 30000 then count( 3)+=1
    if  rand > 30000 and rand < 40000 then count( 4)+=1
    if  rand > 40000 and rand < 50000 then count( 5)+=1
    if  rand > 50000 and rand < 60000 then count( 6)+=1
    if  rand > 60000 and rand < 70000 then count( 7)+=1
    if  rand > 70000 and rand < 80000 then count( 8)+=1
    if  rand > 80000 and rand < 90000 then count( 9)+=1
    if  rand > 90000 and rand <100000 then count(10)+=1
    
next

print "Picked " ; count( 1) ; " between       0  and  10,000"
print "Picked " ; count( 2) ; " between  10,000  and  20,000"
print "Picked " ; count( 3) ; " between  20,000  and  30,000"
print "Picked " ; count( 4) ; " between  30,000  and  40,000"
print "Picked " ; count( 5) ; " between  40,000  and  50,000"
print "Picked " ; count( 6) ; " between  50,000  and  60,000"
print "Picked " ; count( 7) ; " between  60,000  and  70,000"
print "Picked " ; count( 8) ; " between  70,000  and  80,000"
print "Picked " ; count( 9) ; " between  80,000  and  90,000"
print "Picked " ; count(10) ; " between  90,000  and 100,000"

sleep
end

fxm
Moderator
Posts: 12110
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Random Numbers

Post by fxm »

See at KeyPgRandomize:
.....
Note: using the Timer value directly as a parameter will produce the same seed if used more than once in the same second.
.....
Therefore the 'rand' value changes only once at each second.
caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: Random Numbers

Post by caseih »

Why is it even necessary to have the randomize step? Surely modern OS's have enough entropy available. Does not the runtime library use OS-level entropy? Guess I could check the source code.

EDIT: I see that it appears to simply be using the C standard library's rand() and all pseudo-random number generators must be seeded. Best left to the programmer to choose the best way to do that, I see. Seeding from /dev/urandom could be the best way to go.
albert
Posts: 6000
Joined: Sep 28, 2006 2:41
Location: California, USA

Re: Random Numbers

Post by albert »

I took the GenerateKey function and made it standalone for a demonstration...

It keeps picking mid and higher values... almost no picks less than 4 digits..

Code: Select all

    
    dim as longint TabPages = 1024/8
    
    dim as integer Garbagebits = 128*8*1024
    
    Redim as integer Key(0 to (TabPages*64-1) )
        
    dim a as integer
    dim b as integer
    dim c as integer
    dim d as integer
  
    'create random key for main cypher.
    for a = 0 to (TabPages*64)-1
        key(a) = 0
    next
      
    a=0
    do
        b = int(rnd*GarbageBits)+1
        do
            b = int(rnd*GarbageBits)+1
            d = 0
            for c = 0 to a
               if key(c) = b then d = 1 
            next
        loop until d = 0
        key(a) = b
        a = a + 1      
    loop until a=(TabPages*64)      

    'bubble sort key() values
    for a as longint = lbound(key) to ubound(key)
        for b as longint = lbound(key) to ubound(key)
            if key(b)>key(a) then swap key(a),key(b)
        next
    next
    
    dim as longint count(4 to 6)
    for a as longint = lbound(key) to ubound(key)
        print key(a) , 
        
        dim as string num = str(key(a))
        
        if len(num) >= 1 and len(num) <= 4 then count(4)+=1
        if len(num) >= 5 and len(num) <= 6 then count(5)+=1
        if len(num) >= 7 and len(num) <= 8 then count(6)+=1
        
    next
    
    print
    print "numbers >= 1 digits and less <= 4 digits  = " ; count(4)
    print "numbers >= 5 digits and less <= 6 digits  = " ; count(5)
    print "numbers >= 7 digits and less <= 8 digits  = " ; count(6)
    
sleep
end


Heres another example , all 5-6 digits picked...

Code: Select all


dim as longint count(1 to 8192)
for a as longint = 1 to 8192
    count(a) = int(rnd*128*8*1024)
next

dim as longint values(1 to 3)
for a as longint = lbound(count) to ubound(count)
    
    print count(a),
    dim as string num = str(count(a))

    if len(num) >= 0 and len(num) <=  4 then values(1)+=1
    if len(num) >= 5 and len(num) <=  6 then values(2)+=1
    if len(num) >= 7 and len(num) <=  8 then values(3)+=1

next

print
print " >= 0 digits and <= 4 digits " ; values(1)
print " >= 5 digits and <= 6 digits " ; values(2)
print " >= 7 digits and <= 8 digits " ; values(3)

sleep
end

integer
Posts: 408
Joined: Feb 01, 2007 16:54
Location: usa

Re: Random Numbers

Post by integer »

4 digit number: 0000 to 9999
5&6 digits : 10000 to 999999
7&8 digits : 1000000 to 99999999

generated numbers: 0001 to 1048576

9999/1048756 = 0.95% 0.0095*8192 = 78 expected .vs 74 counted
(999999 - 9999)/1048756 *8192 = 7734 expected .vs 7706 counted
(1048756-999999)/1048756 * 8192 = 381 expected .vs 412 counted

It appears that the random number function is generating uniformly distributed numbers, as expected.
You will need to modify the GenerateKey procedure if you are seeking a more biased distribution.
caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: Random Numbers

Post by caseih »

albert wrote:I took the GenerateKey function and made it standalone for a demonstration...

It keeps picking mid and higher values... almost no picks less than 4 digits..
Yes, of course it does, since the pseudo random algorithm is generating an even distribution, as integer says. So of course we'd expect only a small number of numbers to have 4 digits or less. Why would you expect it to behave otherwise? What behavior are you looking for?
Post Reply