-
May 20th, 2013, 07:21 PM
#1
Thread Starter
Hyperactive Member
Legals when "randomly" selecting a winner.
So I found this question I was asked this evening interesting. I was told to, very quickly obviously, make a quick tool that generate a random integer. Easy right? But wait! I suppose there is a twist... This is going to be choosing a winner for a grand price. A grand price grand enough that I wish I could win, but for disclosure I can not say much more Lol. So, I was wondering if there are any legals involved when choosing a "random" winner. In all honesty I feel any computational piece of data a computer generates is never really random, so whats second best?
The only way I know of doing such a task is purely basic at best.
vbnet Code:
Public Class Class1 Private rnd As New System.Random(DateTime.Now.Millisecond) Public Function GenerateRandomInteger(ByVal Minimum As Integer, ByVal Maximum Integer) As Integer Return rnd.Next(Minimum, Maximum) End Function End Class
To get crazy, can we do unique ways of using random.next() to produce a more promising result?
vbnet Code:
Public Class Class1 Private rnd As New System.Random(DateTime.Now.Millisecond) Public Function GenerateRandomInteger(ByVal Minimum As Integer, ByVal Maximum Integer) As Integer Dim col As New System.List(Of Integer) Dim c As Integer = 0 Dim i As Integer = 0 Dim r As Integer = 0 c = rnd.Next(0, 999) i = rnd.Next(0, 999) Do col.Add(rnd.Next(Minimum, Maximum)) While (col.Count < c) r = col(i) Return r End Function End Class
Idk, this is a rather unusual topic for me to ask, but in business development. I find using random numbers nonexistent.
PS I'm not going to use Random.Org
Last edited by DavesChillaxin; May 20th, 2013 at 09:42 PM.
-
May 20th, 2013, 07:35 PM
#2
Re: Legals when "randomly" selecting a winner.
First of all, if you're creating a single Random object then there's no point using the current time as a seed. If you use the constructor with no parameters then it will use the current time anyway, so you may as well just do that. The only reason to use an explicit seed when creating a Random object is that you're creating multiple instances and you need to ensure that a different seed is used in each case.
Secondly, in this case, don't use the Random class. It uses a pseudo-random sequence that is fine for most scenarios but is open to manipulation. In cases like this, you should use the System.Security.Cryptography.RNGCryptoServiceProvider class. It generates data that is sufficiently random to be used in cryptography so it will be fine for what you're doing.
-
May 20th, 2013, 11:52 PM
#3
Thread Starter
Hyperactive Member
Re: Legals when "randomly" selecting a winner.
Originally Posted by jmcilhinney
It uses a pseudo-random sequence that is fine for most scenarios but is open to manipulation. In cases like this, you should use the System.Security.Cryptography.RNGCryptoServiceProvider class. It generates data that is sufficiently random to be used in cryptography so it will be fine for what you're doing.
Whoa! nail on the head. I can now see why the use of the Random class in this situation is bad. And in all honestly coincided my gut feeling! An interesting solution to. I'll be sure to look into it..on my free time of course, now that this is going to be an all nighter, educating myself further on the Cryptography topic thanks Lol
Originally Posted by jmcilhinney
First of all, if you're creating a single Random object then there's no point using the current time as a seed.
and a good catch, I actually blindly followed an example after refreshing my memory with a few web searches. Ya know, just to see if anything's changed since VB6 when I last used it!
But again, time and time again. Flaweless responses. Thanks jmcilhinney!
-
May 21st, 2013, 01:01 AM
#4
Thread Starter
Hyperactive Member
Re: Legals when "randomly" selecting a winner.
Interesting... Here is what I was able to extract from the many examples online. The results seem pretty satisfying to me if I don't say. Feel free to point out any flaw you may notice.
vbnet Code:
Private CryptographicService As New RNGCryptoServiceProvider() ''' <summary> ''' Returns a cryptocraphically generated random number. ''' </summary> ''' <returns>Int32</returns> ''' <remarks>Range has a fixed minimum value of 1.</remarks> Private Function GetRandomInteger(ByVal Maximum As Int32) As Int32 Dim res(0) As Byte ' Create a byte array to hold the random value. Do CryptographicService.GetBytes(res) Loop While res(0)<=Maximum Return (System.Convert.ToInt32(res(0)) Mod Maximum) + 1 ' Values are 0 based. End Function
-
May 21st, 2013, 01:13 AM
#5
Thread Starter
Hyperactive Member
Re: Legals when "randomly" selecting a winner.
Actually the above post works, but not entirely. I need something with a maximum of 37,000, minimum... Perhaps I'm doing this wrong. But when I use 1000 for a maximum, it never produces a value between 1-1000. The values seem to never be greater than 300ish.
hmmmmm....
-
May 21st, 2013, 02:41 AM
#6
Re: Legals when "randomly" selecting a winner.
I would actually inherit the Random class and override the Sample method to use the RNGCryptoServiceProvider class internally, e.g.
Code:
Imports System.Security.Cryptography
Public Class CryptoRandom
Inherits Random
Implements IDisposable
Private ReadOnly rng As New RNGCryptoServiceProvider
Protected Overrides Function Sample() As Double
Dim data(7) As Byte
rng.GetBytes(data)
Dim number = BitConverter.ToDouble(data, 0)
'Normalise the result to the range 0.0 <= N <= 1.0
number = Math.Abs(number / Double.MaxValue)
'Normalise the result to the range 0.0 <= N < 1.0
If number > 0.0 Then
number -= Double.Epsilon
End If
Return number
End Function
#Region "IDisposable Support"
Private disposedValue As Boolean ' To detect redundant calls
' IDisposable
Protected Overridable Sub Dispose(disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
rng.Dispose()
End If
End If
Me.disposedValue = True
End Sub
' This code added by Visual Basic to correctly implement the disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
End Class
You can now use that CryptoRandom class in exactly the same way as you would the regular Random class. It exposes the exact same interface because it inherits its public methods from the regular Random class. Those methods all call Sample internally and the derived CryptoRandom class will use the implementation above that utilises the RNGCryptoRandomServiceProvider instead of the usual pseudo-random sequence generator.
Last edited by jmcilhinney; May 21st, 2013 at 02:45 AM.
-
May 21st, 2013, 09:02 AM
#7
Thread Starter
Hyperactive Member
Re: Legals when "randomly" selecting a winner.
WOW incredible stuff jmcilhinney!
A very neat approach to reuse the Random class. One I didn't even think of doing myself. In all honestly I was trying to stay away from it, but in retrospect I should have done quite the opposite.
This is what I've got so far...
vbnet Code:
Imports System.Security.Cryptography Public Class CryptoRandom Inherits Random Implements IDisposable Private ReadOnly rng As New RNGCryptoServiceProvider() Private _Maximum As Double = 0 Sub New(ByVal Maximum As Double) MyBase.New() Me._Maximum = Maximum End Sub Protected Overrides Function Sample() As Double Dim data(7) As Byte Do Until (BitConverter.ToInt64(data, 0) > 0) rng.GetNonZeroBytes(data) Loop Return BitConverter.ToInt64(data, 0) Mod _Maximum End Function #Region "IDisposable Support" Private disposedValue As Boolean ' To detect redundant calls ' IDisposable Protected Overridable Sub Dispose(disposing As Boolean) If Not Me.disposedValue Then If disposing Then ' Clean up code. 'rng.Dispose() ' Not accessable? I'm confused. End If End If Me.disposedValue = True End Sub ' This code added by Visual Basic to correctly implement the disposable pattern. Public Sub Dispose() Implements IDisposable.Dispose ' Do not change this code. Put cleanup code in Dispose(disposing As Boolean) above. Dispose(True) GC.SuppressFinalize(Me) End Sub #End Region End Class
Wont spend much more time on this, as my boss man told me not to. But when it's interesting and especially a new topic for me, I simple cannot resist.
-
May 21st, 2013, 09:07 AM
#8
Re: Legals when "randomly" selecting a winner.
You should do away with that Maximum business. From the outside, this class works just like the Random class. As such, you simply call Next and specify a maximum and it will return an Integer that is less than that maximum but not less than zero, just as you would with the Random class. The only difference is how the random numbers are generated internally.
-
May 21st, 2013, 10:26 AM
#9
Thread Starter
Hyperactive Member
Re: Legals when "randomly" selecting a winner.
I can't seem to get it to work any other way though. Taking your example, and using .Next(Int32, Int32) to specify a min/max range, I get -2147483648 as a value every single time...
EDIT: Actually I had a bug messing this up going unnoticed, I get 0 every time.
Last edited by DavesChillaxin; May 21st, 2013 at 10:29 AM.
-
May 22nd, 2013, 12:04 AM
#10
Re: Legals when "randomly" selecting a winner.
That's due to an issue in my code. I've reimplemented that CryptoRandom class and posted it in the CodeBank. You can find it here:
http://www.vbforums.com/showthread.p...m-Random-Class
-
May 23rd, 2013, 05:16 PM
#11
Re: Legals when "randomly" selecting a winner.
A few years ago I tried some tests to look at the distribution of random numbers. I was actually looking at getting a weighted distribution, but as an early step I confirmed that the distribution of random numbers returned by Random was suitably even. For a single number or two, Random may have some issues, but over a sizeable sample, it does end up being random because the weighting begins to approach even. It takes a large sample, though, or else a true random distribution is not evenly distributed. That has always made me think that a random selection of the results of a large sample of Random results would be quite random....but also too painful to bother with. This approach appears to be a better one.
My usual boring signature: Nothing
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|