MakeRandomString

Share your advanced PureBasic knowledge/code with the community.
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

MakeRandomString

Post by Mistrel »

Just a little something I whipped up while testing some code. It's not particularly efficient and has lots of room for improvement, for those who are bored.

Code: Select all

Procedure.s MakeRandomString(Length)
  If Not Length
    ProcedureReturn ""
  EndIf
  
  For i=1 To Length
    Number=0
    
    If Random(1,0)
      Number=#True
    EndIf
    
    If Number
      Char.s=Str(Random(9,0))
    Else
      Char.s=Chr(Random(90,65))
    EndIf
    
    RandomString.s+Char.s
  Next i
  
  ProcedureReturn RandomString.s
EndProcedure
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: MakeRandomString

Post by PB »

> lots of room for improvement

Here's an optimized version to remove all redundancy:

Code: Select all

Procedure.s MakeRandomString(Length)
  For i=1 To Length
    If Random(1,0)
      RandomString.s+Str(Random(9,0))
    Else
      RandomString.s+Chr(Random(90,65))
    EndIf
  Next
  ProcedureReturn RandomString.s
EndProcedure
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
infratec
Always Here
Always Here
Posts: 7622
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: MakeRandomString

Post by infratec »

Hi,

since String + String needs a lot of time:

Code: Select all

Procedure.s MakeRandomString(Length)
  
  Protected RandomString.s, *Buffer, i.i
  
  *Buffer = AllocateMemory((Length + 1) * SizeOf(Character))
  If *Buffer
    Length - 1
    For i = 0 To Length
      If Random(1, 0)
        PokeC(*Buffer + i * SizeOf(Character), Random('9', '0'))
      Else
        PokeC(*Buffer + i * SizeOf(Character), Random('Z', 'A'))
      EndIf
    Next
    RandomString = PeekS(*Buffer)
    FreeMemory(*Buffer)
  EndIf
  
  ProcedureReturn RandomString
  
EndProcedure

Code: Select all

StartTime = ElapsedMilliseconds()
Test$ = MakeRandomString(100000)
EndTime = ElapsedMilliseconds()
MessageRequester("Info", "Need " + Str(EndTime - StartTime) + "ms")
Bernd
Fred
Administrator
Administrator
Posts: 18247
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: MakeRandomString

Post by Fred »

For such, a dynamic buffer isn't needed:

Code: Select all

Procedure.s MakeRandomString(Length)
 
  RandomString.s = Space(Length)
  
  Length - 1
  For i = 0 To Length
    If Random(1, 0)
      PokeC(@RandomString + i * SizeOf(Character), Random('9', '0'))
    Else
      PokeC(@RandomString + i * SizeOf(Character), Random('Z', 'A'))
    EndIf
  Next
 
  ProcedureReturn RandomString
EndProcedure
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Re: MakeRandomString

Post by Mistrel »

Still faster. :wink:

Code: Select all

Structure Char
  c.c[0]
EndStructure

Procedure.s MakeRandomString(Length)
  Protected RandomString.s
  Protected Random
  Protected *RandomString.Char
  Protected i
  
  RandomString.s=Space(Length)
  *RandomString=@RandomString.s
  Length-1
  
  For i=0 To Length
    Random=Random(25,0)
    
    If Random%2
      *RandomString\c[i]=65+Random
    Else
      *RandomString\c[i]=48+Random%10
    EndIf
  Next
  
  ProcedureReturn RandomString.s
EndProcedure

Debug MakeRandomString(0)
User avatar
STARGÅTE
Addict
Addict
Posts: 2235
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: MakeRandomString

Post by STARGÅTE »

Code: Select all

Random=Random(25,0)
Random%10
This is no uniform distribution, because you get more numbers between 0 and 5 than numbers between 6 and 9.

I use this RandomString:

Code: Select all


CompilerIf Defined(CharacterArray, #PB_Structure) = #False
	Structure CharacterArray
		c.c[0]
	EndStructure
CompilerEndIf

#RandomString_Numeric = "0123456789"
#RandomString_Letter  = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
#RandomString_Serial  = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"

Procedure.s RandomString(Length.i, CharacterSet.s=#RandomString_Letter)
	
	Protected Index.i, Len.i = Len(CharacterSet)-1
	Protected *CharacterSet.CharacterArray = @CharacterSet
	Protected String.s = Space(Length)
	Protected *String.CharacterArray = @String
	
	While Index < Length
		*String\c[Index] = *CharacterSet\c[Random(Len)]
		Index + 1
	Wend
	
	ProcedureReturn String
	
EndProcedure

Debug RandomString(16)
Debug RandomString(16, #RandomString_Numeric)
Debug RandomString(16, #RandomString_Serial)
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Re: MakeRandomString

Post by Mistrel »

STARGÅTE wrote:

Code: Select all

Random=Random(25,0)
Random%10
This is no uniform distribution, because you get more numbers between 0 and 5 than numbers between 6 and 9.
You could throw another random in there if you want it to be more distributed, sure.

I didn't run any tests but just from observation I think yours might be faster while also being uniform; although it does have a call to Len() which you could store somewhere.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: MakeRandomString

Post by PB »

> you get more numbers between 0 and 5 than numbers between 6 and 9

Which is still perfectly random, you know. ;) By the very definition of "random",
you don't get to "prefer" which numbers get picked more often than any others.
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Re: MakeRandomString

Post by Mistrel »

Wouldn't it be considered pseudorandom if an uneven distribution can be proven?
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: MakeRandomString

Post by PB »

> uneven distribution can be proven

That's a scientific impossibility when it comes to randomness.
Again, you're thinking that randomness MUST have an even
distribution. Random means random: you NEVER know what
the results will be, and there must NEVER be an expectation
or preference of the results.

Think of it like this: just because a coin is flipped 100 times and
99 of those came up heads, doesn't mean it wasn't random. ;)
It's just human nature bitching about the results because they
weren't the results we expected. But that's the very definition
of randomness! :)
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Re: MakeRandomString

Post by Mistrel »

Yes, but given a sufficient sample size you can determine probability.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: MakeRandomString

Post by PB »

If you can determine probability then it's not random. ;)
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Re: MakeRandomString

Post by Mistrel »

That's what I'm saying. :shock:

If it's an uneven distribution then you can calculate probability.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: MakeRandomString

Post by PB »

I misunderstood you. :)
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
User avatar
skywalk
Addict
Addict
Posts: 4219
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: MakeRandomString

Post by skywalk »

Even the slightest bias in a game of chance can result in serious losses for online and brick and mortar casinos.
99 out of a 100 flips would break any casino. :shock:
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
Post Reply