Foro de elhacker.net

Programación => .NET (C#, VB.NET, ASP) => Mensaje iniciado por: Jeezy en 5 Agosto 2018, 05:16 am



Título: Random VB.NET
Publicado por: Jeezy en 5 Agosto 2018, 05:16 am
Hola quiero hacer lo siguiente:
Quiero hacer que en un textbox se pongan numeros random pero no los que quiera sino una secuencia que yo ponga ejemplo
: que se ponga el 1 luego el 20 luego en 50...
y que no se ponga cualquier otro numero solo los que yo diga


Tengo una forma que es usando varios timers, pero quisiera saber si hay otra forma mas optimizada


Título: Re: Random VB.MET
Publicado por: Serapis en 5 Agosto 2018, 17:02 pm
Creas un array, metes ahí todos los números personalizados que quieras...

Luego se trata de eleigr al azar un índice entre 0 y el último índice del array.
Si tienes 25 números en el array, entonces los índices van del 0 al 24.
Y Random debe elegir un valor entre 0 y 24...
Finalmente en tu textbox pones el valor que consta en el array en la posición obtenida al azar...

Para forzar una mayor entropía, con cada número obtenido intercambia el par de valores según indiceprevio e índiceactual.

Y si... si quieres que el número cambie por sí solo, usar un timer está bien, pero recuerda que habrá algún momento en que deba estar activo y alguno en que deba ser desactivado (salvo que solo tenga un propósito decorativo), y recuerda que el lapso de tiempo debe ser algo que mantenga el valor el tiempo suficiente para ser visualizado, o si se trata de simular un 'barajado' puede ser algo más rápido, pero que todavía dé tiempo a poder leer valores...

Código
  1.    Dim miArrayRnd() As Int32 = New Int32() {2, 20, 50, 69, 13, 3, 72, 96, 44, 31, 58, 85, 22, 12, 94, 57, 36, 7, 5, 39, 92, 83, 64, 18, 74}
  2.  
  3.    Dim IndicePrevio As Int32 ' = 0
  4.    Dim IndiceActual As Int32 ' = 0
  5.  
  6.  
  7.  
  8.    Private Sub form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
  9.        Randomize()
  10.    End Sub
  11.  
  12.    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
  13.        Dim tmp As Int32
  14.  
  15.        IndiceActual = CInt(Int((miArrayRnd.Length - 1) * Rnd()))
  16.        TextBox1.Text = miArrayRnd(IndiceActual).ToString
  17.  
  18.        ' intercambiar el par de valores:
  19.        tmp = miArrayRnd(IndiceActual)
  20.        miArrayRnd(IndiceActual) = miArrayRnd(IndicePrevio)
  21.        miArrayRnd(IndicePrevio) = tmp
  22.  
  23.       ' Recordar el índice previo... en la siguiente llamada.
  24.        IndicePrevio = IndiceActual
  25.    End Sub


Título: Re: Random VB.MET
Publicado por: Eleкtro en 5 Agosto 2018, 19:16 pm
Aquí tienes otra forma de hacerlo...

Básicamente declaro un Array con los valores (la ordenación de los valores no importa) y se añaden desordenados a una pila. En cada tic del temporizador se comprueba si la pila está vacía, y si lo está entonces se vuelve a llenar con un una nueva desordenación de los valores. Dicho de otra forma, la secuencia se desordena una vez, se añaden los valores desordenados a una pila, y cuando la pila está vacía la secuencia se vuelve desordenar y se vuelve a llenar la pila con la nueva desordenación. No sé si esto es exactamente lo que quieres hacer, tampoco has dado suficientes detalles...

Código
  1. Public NotInheritable Class Form1 : Inherits Form
  2.  
  3.    Private ReadOnly rng As Random
  4.  
  5.    ' Aquí se define el Array con la secuencia de valores que más tarde serán desordenados...
  6.    Private ReadOnly sequence As Integer() = {1, 2, 3, 4, 5, 6, 7, 8, 9}
  7.    Private stack As Stack(Of Integer)
  8.  
  9.    Public Sub New()
  10.        ' This call is required by the designer.
  11.        MyClass.InitializeComponent()
  12.  
  13.        ' Add any initialization after the InitializeComponent() call.
  14.        Me.rng = New Random(Seed:=Environment.TickCount)
  15.        Me.stack = New Stack(Of Integer)
  16.    End Sub
  17.  
  18.    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  19.        Me.Timer1.Interval = CInt(TimeSpan.FromSeconds(1).TotalMilliseconds)
  20.        Me.Timer1.Enabled = True
  21.        Me.Timer1.Start()
  22.    End Sub
  23.  
  24.    Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As EventArgs) Handles Timer1.Tick
  25.        ' Si la pila está vacía, la llenamos con una nueva secuencia de valores desordenados.
  26.        If (Me.stack.Count = 0) Then
  27.            Me.FillStack(Me.stack, Me.sequence, shuffleValues:=True)
  28.        End If
  29.  
  30.        ' Obtenemos el siguiente valor de la pila.
  31.        Dim nextValue As Integer = Me.stack.Pop()
  32.  
  33.        ' Hacer aquí lo que sea que quieras hacer con el valor obtenido...
  34.        Me.TextBox1.AppendText(CStr(nextValue))
  35.    End Sub
  36.  
  37.    Private Sub FillStack(Of T)(ByRef refStack As Stack(Of T), ByVal values As IEnumerable(Of T), ByVal shuffleValues As Boolean)
  38.        Dim newValues As IEnumerable(Of T) =
  39.            If(shuffleValues, (From value As T In values Order By Me.rng.Next Select value), values)
  40.  
  41.        refStack.Clear()
  42.        For Each value As T In newValues
  43.            refStack.Push(value)
  44.        Next value
  45.    End Sub
  46.  
  47. End Class

La clase Random se basa en un algoritmo de pseudo-aleatoriedad, es más que suficiente para la gran mayoría de escenarios/aplicaciones no-científicas, pero si por lo que sea necesitas un algoritmo de aleatoriedad más sofisticado con mayor entropía, con una distribución de mayor singularidad sobre todos los posibles resultados, entonces usa la clase RNGCryptoServiceProvider.

Saludos.