elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.


 


Tema destacado:


  Mostrar Mensajes
Páginas: 1 2 3 4 [5] 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ... 35
41  Foros Generales / Noticias / Re: Netflix confirma que está bloqueando dispositivos root en: 14 Mayo 2017, 21:39
Desde hace apenas algunas horas, los usuarios de dispositivos móviles Android se están encontrando con que, al descargar Netflix desde la Google Play Store, la tienda de apps lanza un mensaje de error informando de que ‘el dispositivo no es compatible’. Un problema relacionado con los dispositivos rooteados y que, en poco tiempo, Netflix ha confirmado.
Ayyy, el maldito dequeísmo...  >:D >:D >:D >:D

"Informando que..."
42  Foros Generales / Noticias / Re: Chema Alonso (Telefónica) garantiza que los equipos infectados están bajo .... en: 14 Mayo 2017, 21:33
pertenecer a la alta gerencia de una empresa va más allá de ganar un sueldazo y aparecer en la sección de sociales del periodico, es un trabajo 24/7/365, porque ...
La responsabilidad de algo (profesional), queda delimitada, por lo que pone en tu contrato, y punto. De hecho si intentas hacer algo más que no está estipulado en tu contrato, es bastante probable que te paren los pies y te recuerden cual es tu puesto.

Lo que los demás quieran poner en tus espaldas, es problema de su imaginación. Tu mochila la define tu contrato.
43  Foros Generales / Noticias / Re: Microsoft culpa a las empresas del ataque ¿Son responsables por no actualizar... en: 14 Mayo 2017, 21:21
Guau...
Esto es como decir que si hay un atraco en un banco y un atracador mata a alguien, la culpa es del muerto, por ir al banco...

La culpa SIEMPRE es del delincuente, en segundo lugar, será culpa de la seguridad del banco, y solo en último lugar, ¿los afectados podrían haber hecho mejor las cosas?, tal vez sí, tal vez no.
44  Seguridad Informática / Abril negro / Re: [Abril Negro] S.P.O.K (Simple Production Of Keys) en: 13 Mayo 2017, 04:46
Continuamos...
El segundo algoritmo, es básicamente un esquema de revólver, exactamente tal y como es un cuentakilómetros.

La idea básica detrás de ello, es que hay un bucle por cada carácter. Y ese bucle se encarga de iterar exclusivamente ese carácter, al final del mismo (o antes de entrar) se pone el valor inicial de nuevo (esto es automático en los bucles for, ya que en ellos se declara explícitamente dichos valores de inicio y fin).
En cada bucle, por tanto se establece el valor actual en la posición que ocupa en el término permutado.
Cuando se alcanza el bucle interior, en cada iteración de éste, se obtiene ya la permutación completa.

La ventaja de este algoritmo (genérico), sobre el declarado en el mensaje previo, es que no requiere con cada permutación generar cada vez todos sus caracteres. La forma más clara de visualizar este algorimo, se refleja en un cuentakilómetros...

De este algoritmo expondré tres variaciones, la primera basada en un bucle for.
- La ventaja de éste algoritmo sobre el anterior es la velocidad gracias a evitar, la continua generación de caracteres que no cambia en la siguiente iteración.
- Su desventaja (como bucle for), la dificultad de establecer el punto inicial desde el que comenzar si no es, el comienzo de la permutación. Las variantes posteirores para este algoritmo solventan este problema.

Ahora ya vayamos con el código, para el mismo se ha provisto también una ventana y una clase que realiza el trabajo. Si bien la ventana será la misma para las tres variantes del algoritmo.

Aquí una vista de la interfaz, muy sencilla y el resultado tras la ejecución.


El código de la interfaz, es bien sencillo, básicamente se instancia la clase, y se invoca el método enumerar con los parámetros que aparecen en los textos. En esta versión, no se usa el valor de estado inicial, o dicho de otra manera, el valor de comienzo está fijado al comienzo de la iteración.

Código
  1. Public Class frm2 ' la ventana, formulario
  2.    Private buc As New cBucAni ' instancia a la clase usada
  3.  
  4.    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
  5.        Dim Min() As Byte, Max() As Byte
  6.        Dim z As Decimal
  7.  
  8.        Min = StringToByteArray(TextBox2.Text)  ' Valor mínimo: Ejemplo: "AAAAZ"
  9.        Max = StringToByteArray(TextBox3.Text)  ' Valor final, Ejemplo: "ZWZZA
  10.  
  11.        z = buc.EnumerarFor(Min, Max)
  12.    End Sub
  13.  
  14.    Private Function StringToByteArray(ByRef Txt As String) As Byte()
  15.        Return System.Text.Encoding.Unicode.GetBytes(Txt)
  16.    End Function
  17. End Class
  18.  
- El código, primero se crea una instancia de la clase (llamada: "cBucAni", son bucles anidados, no me he complicado con el nombre).
- Luego el código del botón. Primero llama a una función para obtener los bytes (2 bytes por carácter) respectivos a los textos de límite de la enumeración. Luego invoca el método enumerar.
- La función devuelve la cantidad de permutaciones (aunque luego no usamos ese valor para nada). El tipo de datos Decimal, es un tipo de 96bits, + 1 bit de signo... Puede ponerse un tipo de bytes (64bits), después de todo, no es estrictamente necesario devolver la cantidad de permutaciones.

Vayamos con el código de la clase para esta variante del algortimo-B:

Código
  1. Public Class cBucAni
  2.  
  3.  
  4.    Public Function EnumerarFor(ByRef sMin() As Byte, ByRef sMax() As Byte) As Decimal
  5.        Dim a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p As short  ' 16bits con signo
  6.        Dim Max(0 To 15) As Short
  7.        Dim Min(0 To 15) As Short
  8.        Dim Inc(0 To 15) As Short
  9.        Dim SizeClave As Short  ' Tamaño de las claves (cantidad de caracteres que contienen)
  10.        Dim ClavePermutada() As Byte  ' Clave generada en bytes.
  11.  
  12.        Dim t As Byte
  13.        Dim z As Decimal, Crono As Single
  14.        Dim txt As String
  15.  
  16.        Crono = TimeOfDay.Ticks ' ticks desde medianoche hasta la hora actual
  17.  
  18.        z = CalcularNumPermutaciones(sMin, sMax)
  19.        If (z < 0) Then
  20.            Return -1
  21.            Exit Function
  22.        Else
  23.            SizeClave = sMin.Length
  24.            ReDim ClavePermutada(0 To SizeClave - 1)
  25.  
  26.            For t = 0 To (SizeClave - 2) Step 2
  27.                Max(n) = sMax(t)
  28.                Min(n) = sMin(t)
  29.                n += 1
  30.            Next
  31.            For t = 0 To n - 1 '((SizeClave \ 2) - 2)
  32.                If (Max(t) > Min(t)) Then
  33.                    Inc(t) = 1
  34.                ElseIf (Max(t) < Min(t)) Then
  35.                    Inc(t) = -1
  36.                End If
  37.            Next
  38.  
  39.            For t = n To 15 'SizeClave To 15
  40.                Inc(t) = 256
  41.                Min(t) = -1
  42.                Max(t) = -1
  43.            Next
  44.  
  45.        End If
  46.  
  47.        For p = Min(15) To Max(15) Step Inc(15)
  48.            If (p >= 0) Then
  49.                ClavePermutada(30) = p
  50.            End If
  51.            For o = Min(14) To Max(14) Step Inc(14)
  52.                If (o >= 0) Then
  53.                    ClavePermutada(28) = o
  54.                End If
  55.                For n = Min(13) To Max(13) Step Inc(13)
  56.                    If (n >= 0) Then
  57.                        ClavePermutada(26) = n
  58.                    End If
  59.                    For m = Min(12) To Max(12) Step Inc(12)
  60.                        If (m >= 0) Then
  61.                            ClavePermutada(24) = m
  62.                        End If
  63.                        For l = Min(11) To Max(11) Step Inc(11)
  64.                            If (l >= 0) Then
  65.                                ClavePermutada(22) = l
  66.                            End If
  67.                            For k = Min(10) To Max(10) Step Inc(10)
  68.                                If (k >= 0) Then
  69.                                    ClavePermutada(20) = k
  70.                                End If
  71.                                For j = Min(9) To Max(9) Step Inc(9)
  72.                                    If (j >= 0) Then
  73.                                        ClavePermutada(18) = j
  74.                                    End If
  75.                                    For i = Min(8) To Max(8) Step Inc(8)
  76.                                        If (i >= 0) Then
  77.                                            ClavePermutada(16) = i
  78.                                        End If
  79.                                        For h = Min(7) To Max(7) Step Inc(7)
  80.                                            If (h >= 0) Then
  81.                                                ClavePermutada(14) = h
  82.                                            End If
  83.                                            For g = Min(6) To Max(6) Step Inc(6)
  84.                                                If (g >= 0) Then
  85.                                                    ClavePermutada(12) = g
  86.                                                End If
  87.                                                For f = Min(5) To Max(5) Step Inc(5)
  88.                                                    If (f >= 0) Then
  89.                                                        ClavePermutada(10) = f
  90.                                                    End If
  91.                                                    For e = Min(4) To Max(4) Step Inc(4)
  92.                                                        If (e >= 0) Then
  93.                                                            ClavePermutada(8) = e
  94.                                                        End If
  95.                                                        For d = Min(3) To Max(3) Step Inc(3)
  96.                                                            If (d >= 0) Then
  97.                                                                ClavePermutada(6) = d
  98.                                                            End If
  99.                                                            For c = Min(2) To Max(2) Step Inc(2)
  100.                                                                If (c >= 0) Then
  101.                                                                    ClavePermutada(4) = c
  102.                                                                End If
  103.                                                                For b = Min(1) To Max(1) Step Inc(1)
  104.                                                                    If (b >= 0) Then
  105.                                                                        ClavePermutada(2) = b
  106.                                                                    End If
  107.  
  108.                                                                    For a = Min(0) To Max(0) Step Inc(0)
  109.                                                                        ClavePermutada(0) = a
  110.                                                                        ' Usar Permutación desde aquí:
  111.                                                                        'txt = System.Text.Encoding.Unicode.GetString(ClavePermutada)
  112.                                                                        ' call FuncionX(ClavePermutada)
  113.                                                                    Next
  114.                                                                Next
  115.                                                            Next
  116.                                                        Next
  117.                                                    Next
  118.                                                Next
  119.                                            Next
  120.                                        Next
  121.                                    Next
  122.                                Next
  123.                            Next
  124.                        Next
  125.                    Next
  126.                Next
  127.            Next
  128.        Next
  129.  
  130.  
  131.        ' Devolver resultados        
  132.        Crono = ((TimeOfDay.Ticks - Crono) / 10000000)  ' ticks hasta la hora actual, menos los de comienzo= ticks invertidos en la tarea.
  133.        txt = System.Text.Encoding.Unicode.GetString(ClavePermutada)
  134.        MessageBox.Show("Tiempo: " & Crono.ToString & vbCrLf & "Permutaciones: " & z.ToString & vbCrLf & "Ultima clave Permutada: " & txt)
  135.        Return z
  136.    End Function
  137.  
  138. ' ....
  139. End Class
  140.  
Como se ve la clase contiene exclusivamente un metodo (EnumerarFor), que admite dos parámetros. El comienzo de la iteración para cada carácter y el final de iteración para cada carácter.
Una particularidad extra de este algoritmo (en las 3 variantes), es que se ha modificado la forma del alfabeto que utiliza (ya vimos en el algoritmo previo diferentes formas de expresar un alfabeto). Con sólo esos dos parámetros, en realidad estamos definiendo un alfabeto exclusivo para cada carácter, además de dejar claro, el largo de las claves que se van a generar (tan largas como caracteres tienen ambos parámetros. De hecho es requisito que ambos parámetros sean igual de largos.
Esto hace popsible que si deseamos generar claves en la forma:
  AAAA-000-xx:QQQQ
  ZZZZ-999-pp:DDDD
Puede entenderse que para los 4 primeros caracteres (a la izquierda), el rango del alfabeto está en: A-Z, luego viene un guión fijo, los dos siguientes caracteres fijan su alfabeto al rango x-p, el siguiente carácter está fijo al carácter ":" y los 4 últimos caracteres usan un alfabeto en el rango Q-D (nótese que es decreciente)...

Partiendo de esta funcionalidad, es fácil deducir, otra donde delimitamos la entrada de un texto circunscrito a determinado rango de valores, para cada carácter y declaramos no válidos el resto.

Esto facilita enormemente la definición de alfabetos para cada carácter, al no exigir explicítamente un array por cada carácter, y en cuanto al código, implementar esto en el algoritmo, del mensaje previo (el definido como algoritmo A), sería complejo y la cantidad de comparaciones para delimitarlo, lo harían extremadamente lento, en éste en cambio, no existe penalización alguna (salvo una verificación inicial prácticamente sin coste en realción al tiempo empleado en la enumeración) ni exige arrays de alfabetos...
Eso sí, la definición de este alfabeto, establece el orden ASCII, es decir si definimos un inicion y fin como:
   00000000
   ZZZZZZZ
En realidad estamos definiendo un rango entre los caracteres ASCII '0' y 'Z', no del 0-9 y A-Z... y justamente se suceden en el orden en que aparecen en el ASCII... si no fuera el caso, sería necesario un Array que defina los caracteres y el orden que ocupan (o varios si cada carácter tuviera su propia evolución).

- Tras acceder a la enumeración, lo primero es contar las permutaciones resultantes, y una verificación de validez de los parámetros. Para ello se invoca una función que está en un módulo privado del proyecto pero común a todo el proyecto. Se explica más abajo dicha función, aquí baste decir que si los parámetros no son consecuentes, devuelve un valor negativo que fuerza la salida de la función y que debe interpretarse como error...

- Luego se genera un array de bytes (2  por cada carácter) del mismo tamamo que los parámetros, que será donde se deposite el resultado de la enumeración... y que se irá sobrescribiendo una y otra vez...

- Lo siguiente es establecer los valores adecuados para el inicio, final del bucle y dirección de avance (puede ir tanto desde A-Z, como desde Z-A, por tanto el bucle puede aumentar o reducir en unidades.

- Lo siguiente, si se mira bien, es que hay 16 bucles, esto implica que con la misma función, sin cambios, podríamos generar claves de largo entre 1 y 16. Las claves se generan en los bucles más internos, y quedan sin usar los bucles más externos, para estos se fijan Min, Max e Incremento a valores que hacen que el bucle se ejecute una sola vez y por tanto no alteran ni se cae en errores.

- Finalmente vienen los bucles, extreamadamente sencillos y que puede verse cómo actúan exactamente como los cuentakilómetros.
Se ha recurrido a señalar cada bucle, como a,b,c,d,e...p, el bucle 'a', es el más interno y sobre la clave produce el carácter 0, el más externo (el bulce 'p'), produce el último carácter (si usan claves de 16 caracteres.


A continuación adjunto el código de la función que se invoca a al entrada de la función enumerar... y que tiene por objeto contar el número de permutaciones que se van a generar y verificar un par de cosas: que ambos parámetros tienen el mismo tamaño de caracteres (podría añadirse una verificación de delimitación del tamaño mínimo (1) y máximo (16) caracteres, que no se realiza), puede ocurrir un error si el número de permutaciones sobrepasa el rango de 96 bits (12 bytes, pués se ha declarado la cuenta con un tipo de datos
Decimal). Nótese que los bucles no generarán error por desbordamiento, opera simplemente con 8 y 16 bits (byte y short) y el tamaño, simplemente es tiempo que tarda. Si se prefiere evitardesbordamiento incluso para 96 bits, puede omitirse la cuenta de permutaciones y devolverlo en formato de string en la forma X a la Y (26^7), (36^5), (256^16), etc...

Código
  1. ''' <summary>
  2.    ''' Calcula el número de permutaciones totales.
  3.    ''' </summary>
  4.    ''' <param name="Min">Define el valor mínimo para cada carácter.</param>
  5.    ''' <param name="Max">Define el valor máximo para cada carácter.</param>
  6.    ''' <returns>El número de permutaciones totales. Un valor negativo, si hubo errores.</returns>
  7.    ''' <remarks>Cada carácter tiene su propio alfabeto, circunscrito al rango Min-Max, para el índice que ocupa.</remarks>
  8.    Friend Function CalcularNumPermutaciones(ByRef Min() As Byte, ByRef Max() As Byte) As Decimal
  9.        Dim k As Short, j As Short, n As Decimal, v As Short
  10.  
  11.        k = Min.Length
  12.        If (k <> Max.Length) Then
  13.            MsgBox("Los 2 arrays deben ser del mismo tamaño: Min y Max.")
  14.            Return -2
  15.            Exit Function
  16.        End If
  17.  
  18.        Try
  19.            n = 1
  20.            For j = 0 To k - 2 Step 2
  21.                v = Max(j) ' impide que la resta entre dos bytes (a continuación), de error por desbordamiento, si el resultado es menor de 0.
  22.                v = (v - Min(j))
  23.                n = (n * (Math.Abs(v) + 1)) ' ABS= Valor absooluto del número (esto es, ignora el signo y lo toma como positivo).
  24.            Next
  25.  
  26.            Return n
  27.        Catch ' de ocurrir un error se espera que sea desbordamiento... (de n).
  28.            Return -1
  29.        End Try
  30.    End Function
  31.  


Finalmente comentar que el código (el del algoritmo de permutación, no esta última función), pero resuelve el caso y es más rápido que el algortimo presentado anteriormente (en el mensaje previo), en contra tiene que no es cómodo establecer un punto de inicio distinto al inicio de las permutaciones, y también que el código no es muy elegante.

Y eso es todo por hoy...

En el próximo mensaje proveeré una variante que resuelve ambas cosas a costa de una pérdida de eficiencia en velocidad, debida a que recurro a un modelo recursivo, frente a este iterativo, además la recursividad será sobre una clase, no sobre un método.

---------------------
p.d.: Un tick en NET es la diezmillonésima parte de 1 sg. por ello al final se divide entre 10 millones, para tener el tiempo en segundos.
45  Foros Generales / Noticias / Re: FBI recomienda a víctimas de hackeo en Hollywood que paguen extorsiones en: 13 Mayo 2017, 01:43
Cabe preguntarse si los hackers de esas extorsiones no serían personal propio del FBI, razón por la cual, tendría sentido recomendar el pago de los rescates...
46  Foros Generales / Noticias / Re: El romance de Microsoft con Linux se intensifica, pero, ¿qué gana la empresa ... en: 13 Mayo 2017, 00:30
Creo que es innecesario.
Básicamente porque son dos filosofías reñidas entre sí. Y lo que unos usuarios quieren lo encuentran en lo que eligen, si quisierna lo otro, se pasarían al otro sistema o viceversa...

Probablemente seremos los programadores, los más beneficiados del asunto, pero los usuarios creo que no tanto, por no decir prácticamente nada.
47  Foros Generales / Noticias / Re: Youtuber ruso es condenado a prisión suspendida por jugar Pokémon Go en una ... en: 13 Mayo 2017, 00:23
Un poco exagerado...
Vale que lo hizo deliberadamente, y por ello ciertamente implica una falta de respeto, pero...
Yo creo que un par de collejas y a lo sumo una semana de cárcel, sobraba como escarmiento.
48  Foros Generales / Noticias / Re: Devorando la Red: 'App' china desafía a WhatsApp, Facebook, Instagram, Skype,... en: 11 Mayo 2017, 04:13
Mi banco es el ICBC (International and Commercial Bank of China) y nunca me ha faltado un centavo (por ahora)...  :xD

La anonimicidad, amigo, marca la diferencia...



Igualmente pasa con el hackeo...
49  Seguridad Informática / Abril negro / Re: [Abril Negro] S.P.O.K (Simple Production Of Keys) en: 11 Mayo 2017, 04:03
Voy a ir poniendo código, aunque sea cada día un algoritmo... y los comentarios pertinentes.... al final, comprimo el proyecto y lo subiré a una pagina de descarga...

Tal como dije me he ceñido estrictamente a no usar clases o métodos complejos, que haga inentendible el código para alguien no versado en Net...

De entrada paso a explicar, que en cad algoritmo he tratado de desarrollarlo de la forma que me ha parecido más adecuada, para traerlo aquí y explicar detalles... esto supone que por ejemplo en alguno habrá muchos detalles previos al algoritmo, y en otros apenas nada, en unos las claves vendrás con 2 bytes por carácter y en otro con uno, en unos con un tipo de datos y en otro con otros... debe quedar claro en todo momento, que al final hablamos siempre de bytes y solo bytes, luego nadie debiera tener dificultad alguna (si conoce adecuadamente el lenguaje que acostumbra a usar), para convertirlo al tipo de datos que precise según el uso al que se destine. Por ejemplo, si alguien se empeña guardarlo a disco, guardar los caracteres con 1 solo byte por carácter ocupará la mitad de espacio que si lo guarda con 2 bytes por caracter... del mismo modo, si lo guarda a disco, prescindir de saltos de línea también ahorra espacio... Después de todo abrir un fichero de pongamos 1Gb. para leerlo, carece de sentido y por lo mismo, da igual que no sea legible y no se abara con un visor de texto o se use un editor  hexadeciaml....

Dicho lo cual, vamos con el primero, el algoritmo-A.

El algoritmo-A, es el más simple de todos en cuanto a líneas de código y como dije es solo un cambio de base de numeración a la base cuyo tamaño representa el alfabeto usado. Es el algoritmo al que todo el mundo (que sepa un mínimo de programación debiera llegar...
- Su fuerte, la extrema sencillez de entenderlo... (y programarlo).
- Su defecto, que no es el más óptimo en cuanto a velocidad. Aún así, para pequeños diccionarios de hasta 5 caracteres (o incluso 6, dada la velocidad de los equipos de hoy día es suficientemente rápido si nios limitamos a un alfabeto de por ejemplo A-Z (entiéndase A-Z, como el rango de caracteres entre ellos dos: "A,B,C,D,E,F...,X,Y,Z").

Dado que este algoritmo es sencillo, me he parado en detalles extras, de los que he prescindido en los otros. También está profusamente lleno de comentarios sobre el código, en los demás he prescindido de tanto detalle.

Aquí una imagen de la interfaz, muy sencilla. Puede verse el selector de tamaño de las claves, el selector del conjunto de caracteres que formarán el alfabeto a permutar y el botón para realizar la tarea.
El conjunto de caracteres puede optarse por todo el ASCII (o una parte definiendo un punto de inicio y una cantidad de caracteres), o restringido a los caracteres: 0-9, A-Z, a-z, o cualquier combinación de ellas (pero siempre en el orden en que aparecen. También permite recibir un alfabeto personalizado (básicamente un array con los caracteres que se desee y en el orden que se quiera). Para el propósito de este texto es suficiente (me parece), pero cada cual que modifique a su gusto...




El código para este algoritmo, se resume en el código asociado a los eventos de la interfaz de usuario y una clase. Esta clase tiene otra interna (anidada), dedicada a generar el alfabeto. Se deja anidada solo por encapsulación, si un lenguaje no admite crear clases anidadas, igualmente se puede dejar fuera...
Vamos pués primero con el código de esta clase anidada:

Esta clase se la ha llamado: AlfabetoToUse
Código
  1. #Region "clase para generar el alfabeto"
  2.  
  3.    ''' <summary>
  4.    ''' Facilitador para crear el alfabeto a usar.
  5.    ''' </summary>
  6.    ''' <remarks></remarks>
  7.    Public Class AlfabetoToUse
  8.        Private p_Alfabeto(0 To 255) As Byte    ' 08 bits
  9.        Private p_Sizealfabeto As Short         ' 16 bits
  10.  
  11.        ''' <summary>
  12.        ''' Facilita la generación automática del alfabeto, basado en un valor que identifica claramente el conjunto que se toma.
  13.        ''' </summary>
  14.        ''' <remarks></remarks>
  15.        Public Enum CaracteresUsadosEnAlfabeto
  16.            ''' <summary>
  17.            ''' Este valor o inferior es un valor ilegal.
  18.            ''' </summary>
  19.            ''' <remarks></remarks>
  20.            ALFABETO_VALOR_ILEGAL_MENOR = -2
  21.            ''' <summary>
  22.            ''' El cliente pasa el array con el alfabeto que desea usar.
  23.            ''' </summary>
  24.            ''' <remarks></remarks>
  25.            ALFABETO_CUSTOM = -1
  26.            ''' <summary>
  27.            ''' El alfabeto es todo el espacio ASCII.
  28.            ''' </summary>
  29.            ''' <remarks></remarks>
  30.            ALFABETO_ASCII = 0
  31.            ''' <summary>
  32.            ''' El alfabeto contiene los números.
  33.            ''' </summary>
  34.            ''' <remarks></remarks>
  35.            ALFABETO_09 = 1
  36.            ''' <summary>
  37.            ''' El alfabeto contiene las mayúsculas (no 'Ñ' ni otros caracteres extendidos).
  38.            ''' </summary>
  39.            ''' <remarks></remarks>
  40.            ALFABETO_AZ_UPPERCASE = 2
  41.            ''' <summary>
  42.            ''' El alfabeto contiene las minúsculas (no 'ñ' ni otros caracteres extendidos).
  43.            ''' </summary>
  44.            ''' <remarks></remarks>
  45.            ALFABETO_AZ_LOWERCASE = 4
  46.            ''' <summary>
  47.            ''' El alfabeto es tomado parcialmente del ASCII
  48.            ''' </summary>
  49.            ''' <remarks></remarks>
  50.            ALFABETO_OFFSET = 8
  51.            ''' <summary>
  52.            ''' Este valor o superior es un valor ilegal.
  53.            ''' </summary>
  54.            ''' <remarks></remarks>
  55.            ALFABETO_VALOR_ILEGAL_MAYOR = 9
  56.        End Enum
  57.  
  58.        Public ReadOnly Property Alfabeto() As Byte()    ' 8 bits
  59.            Get
  60.                Alfabeto = p_Alfabeto
  61.            End Get
  62.        End Property
  63.        Public ReadOnly Property SizeAlfabeto As Short ' 16 bits
  64.            Get
  65.                SizeAlfabeto = p_Sizealfabeto
  66.            End Get
  67.        End Property
  68.  
  69.        ''' <summary>
  70.        ''' Por defecto, el alfabeto es el ASCII y el tamaño 256.
  71.        ''' </summary>
  72.        ''' <remarks>Si las claves han de ser imprimibles como texto, se perderán aquellos caracteres no imprimibles. en tal caso definir el alfabeto a usar.</remarks>
  73.        Public Sub New()
  74.            'Me.New(0)
  75.            p_Sizealfabeto = 256
  76.            Call ConstruyeAlfabeto(CaracteresUsadosEnAlfabeto.ALFABETO_ASCII)
  77.        End Sub
  78.  
  79.        ''' <summary>
  80.        ''' Facilita la construcción del alfabeto basado en un valor de enumeración.
  81.        ''' </summary>
  82.        ''' <param name="Tipo">Pueden unirse entre sí los conjuntos: 0-9, A-Z y a-z (pero será en ese orden)</param>
  83.        ''' <remarks>Aunque el valor 'custom' consta en la enumeración, es el cliente qien debe expresar en ese caso el conjunto de caracteres que se emplea.</remarks>
  84.        Public Sub New(ByVal Tipo As CaracteresUsadosEnAlfabeto)
  85.            If (ConstruyeAlfabeto(Tipo) = False) Then
  86.                Err.Raise(-1, , "El 'tipo' recibido, no consta en la enumeración y/o no permite deducir el conjunto de caracteres a tomar para generar el alfabeto. Introduzca un valor en el rango admitido.")
  87.            End If
  88.        End Sub
  89.  
  90.        ''' <summary>
  91.        ''' Permite declarar un alfabeto parcialmente indicando un desplazamiento sobre la tabla ASCII
  92.        ''' </summary>
  93.        ''' <param name="Comienzo">Punto de comienzo desde donde se toma el alfabeto.</param>
  94.        ''' <param name="SizeAlfabeto">Cantidad de caracteres que se toman del alfabeto. Si es preciso se trunca.</param>
  95.        ''' <remarks>Ejemplo: para generar un alfabeto que use solo las mayúsculas se llamaría con New(65,26)</remarks>
  96.        Public Sub New(ByVal Comienzo As Byte, Optional ByRef SizeAlfabeto As Byte = 255)
  97.            If (Comienzo < 255) Then
  98.                If (SizeAlfabeto + Comienzo > 255) Then
  99.                    SizeAlfabeto = (255 - Comienzo)
  100.                End If
  101.                p_Sizealfabeto = (SizeAlfabeto + 1)
  102.  
  103.                Call ConstruyeAlfabeto(CaracteresUsadosEnAlfabeto.ALFABETO_OFFSET, Comienzo)
  104.            Else
  105.                Err.Raise(-1, , "Si el comienzo es el byte 255, el tamaño del diccionario es 1 y solo genera una clave. ...¿qué sentido tiene???")
  106.            End If
  107.        End Sub
  108.  
  109.        ''' <summary>
  110.        ''' Permite al usuario introducir su propio alfabeto.
  111.        ''' </summary>
  112.        ''' <param name="AlfabetoCustom">Array con el alfabeto del usuario.</param>
  113.        ''' <remarks>OJO: No se verifica la validez del alfabeto, se supone correcto.</remarks>
  114.        Public Sub New(ByRef AlfabetoCustom() As Byte)
  115.            p_Alfabeto = AlfabetoCustom
  116.            p_Sizealfabeto = p_Alfabeto.Length
  117.  
  118.            If (p_Sizealfabeto = 0) Then
  119.                Err.Raise(-1, , "El alfabeto del usuario no puede estar vacío, o tener solo 1 elemento. ...¿con qué fin???")
  120.            End If
  121.        End Sub
  122.  
  123.        ''' <summary>
  124.        ''' Recrea el alfabeto basado en la enumeración recibida
  125.        ''' </summary>
  126.        ''' <param name="Tipo">Enumeración que señala qué caracteres se tomarán para el alfabeto. Los conjuntos 0-9, A-Z y a-z, pueden aunarse entre sí.</param>
  127.        ''' <returns>Devuelve True si el tipo recibido es existente o subyacente en la enumeración</returns>
  128.        ''' <remarks>No se debe invocar el tipo 'custom'</remarks>
  129.        Friend Function ConstruyeAlfabeto(ByVal Tipo As CaracteresUsadosEnAlfabeto, Optional ByVal Offset As Byte = 0) As Boolean
  130.            Dim k As Short, n As Short
  131.  
  132.            n = 0 ' por claridad
  133.            If (Tipo > CaracteresUsadosEnAlfabeto.ALFABETO_CUSTOM) And (Tipo < CaracteresUsadosEnAlfabeto.ALFABETO_VALOR_ILEGAL_MAYOR) Then
  134.                Select Case Tipo
  135.                    Case CaracteresUsadosEnAlfabeto.ALFABETO_ASCII, CaracteresUsadosEnAlfabeto.ALFABETO_OFFSET
  136.  
  137.                        For k = Offset To (p_Sizealfabeto + Offset) ' 0 to 255, si es ASCII
  138.                            p_Alfabeto(n) = k
  139.                            n += 1 ' n=k si offset=0
  140.                        Next
  141.                    Case Else
  142.                        p_Sizealfabeto = 0
  143.                        ' Intervienen los números?
  144.                        If ((Tipo And CaracteresUsadosEnAlfabeto.ALFABETO_09) = CaracteresUsadosEnAlfabeto.ALFABETO_09) Then
  145.                            For k = 48 To 57
  146.                                p_Alfabeto(n) = k
  147.                                n += 1
  148.                            Next
  149.                        End If
  150.  
  151.                        ' intervienen las mayúsculas?. Si sí, añadirlas (tras lo previo)
  152.                        If ((Tipo And CaracteresUsadosEnAlfabeto.ALFABETO_AZ_UPPERCASE) = CaracteresUsadosEnAlfabeto.ALFABETO_AZ_UPPERCASE) Then
  153.                            For k = 65 To 90
  154.                                p_Alfabeto(n) = k
  155.                                n += 1
  156.                            Next
  157.                        End If
  158.  
  159.                        ' Intervienen las minúsculas?. Si sí, añadirlas (tras lo previo)
  160.                        If ((Tipo And CaracteresUsadosEnAlfabeto.ALFABETO_AZ_LOWERCASE) = CaracteresUsadosEnAlfabeto.ALFABETO_AZ_LOWERCASE) Then
  161.                            For k = 97 To 122
  162.                                p_Alfabeto(n) = k
  163.                                n += 1
  164.                            Next
  165.                        End If
  166.  
  167.                        p_Sizealfabeto = n
  168.                End Select
  169.  
  170.                Return True
  171.            Else
  172.                Return False ' el tipo recibido no permite deducir el conjunto de caracteres a tomar para generar el alfabeto.
  173.            End If
  174.        End Function
  175.    End Class
  176.  
  177. #End Region
  178.  

- En dicho código, aparece primero la declaración de variables a nivel de clase, luego una enumeración, que define que tipo de alfabeto se va a construir (si se ha de construir).
- Luego aparecen de propiedades de solo lectura (El alfabeto y el tamaño del alfabeto), ambas propiedades serán las que se lean cuando se use el algoritmo.
- Luego hay 4 constructores de clase, para permitir invocar el tipo de alfabeto de que se quiere generar en base a las opciones que permite.
- Finalmente hay un método que construye el alfabeto.

La idea de esta clase, es que el alfabeto sea definido una sola vez y pueda ser usada como parámetro para enumerar. Así se evita que mientras se enumere se modifique el alfabeto (o el tamaño del mismo) y dé lugar a errores durante la ejecución. Ya que se construye y luego es de solo lectura, no puede modificarse mientras se usa.

Pasamos ahora al código de la clase (llamada cBaseNum) que hospeda a ésta recién descrita (AlfabetoToUse): 
Código
  1. ''' <summary>
  2. ''' Clase: Combinatoria-Alfabeto-Diccionario. Crea diccionario (in situ), mediante combinatoria.
  3. ''' </summary>
  4. ''' <remarks>No se ha previsto en ningún momento almacenar a fichero el diccionario creado</remarks>
  5. Public Class cBaseNum
  6.    ' siempre contiene 256 bytes, aunque luego no se usen todos.
  7.    Private p_Alfabeto(0 To 255) As Byte  ' 08 bits sin signo
  8.    Private p_Sizealfabeto As Short       ' 16 bits con signo
  9.    Private s_LargoClaves As Byte
  10.    Private s_MaxPermutaciones As UInt32    ' 64 bits sin signo
  11.  
  12.  
  13. #Region "clase para generar el alfabeto"
  14.  
  15.    ''' <summary>
  16.    ''' Facilitador para crear el alfabeto a usar.
  17.    ''' </summary>
  18.    ''' <remarks></remarks>
  19.    Public Class AlfabetoToUse
  20. '... AQUI: va el código d ela clase anterior (que está anidada). Si un lenguej no permite anidar clases, dejarla fuera al mismo nivel y listo.
  21.    End Class
  22.  
  23. #End Region
  24.  
  25.    Public Structure PermutarDatosImprescindibles
  26.        Public Charset As AlfabetoToUse
  27.        Public LargoClaves As Byte
  28.        Public PermutacionInicialStr As String
  29.        Public PermutacionInicialLng As Long
  30.    End Structure
  31.  
  32.    ''' <summary>
  33.    ''' Enumera todas las permutaciones.
  34.    ''' </summary>
  35.    ''' <param name="Datos">Alfabeto que se va a usar, Tamaño de las claves a generar y valor inicial.</param>
  36.    ''' <remarks>El método usado en este algoritmo es la conversión entre sistemas de numeración.</remarks>
  37.    Public Sub Enumerar(ByRef Datos As PermutarDatosImprescindibles)
  38.        Dim Clave() As Byte
  39.        Dim k As UInt32, n As Short ' contadores de bucle
  40.        Dim v As UInt32, x As Byte, Numchars As Short
  41.        Dim Crono As Single
  42.  
  43.        Crono = TimeOfDay.Ticks ' ticks a la hora actual
  44.        With Datos
  45.            p_Alfabeto = .Charset.Alfabeto
  46.            p_Sizealfabeto = .Charset.SizeAlfabeto
  47.            s_LargoClaves = .LargoClaves
  48.  
  49.            s_MaxPermutaciones = (p_Sizealfabeto ^ s_LargoClaves)
  50.  
  51.            Numchars = ((s_LargoClaves * 2) - 2)
  52.            ReDim Clave(0 To Numchars + 1)
  53.  
  54.            If (.PermutacionInicialLng < 0) Then .PermutacionInicialLng = 0
  55.            If (.PermutacionInicialStr.Length > 0) Then
  56.                ' FALTA: código para convertir la clave a la enésima permutación.
  57.                ' es el proceso inverso al seguido en el algoritmo y debiera facilitarse como una función pública.
  58.                ' k= EnesimaPermutacion(.PermutacionStr)
  59.            Else
  60.                k = .PermutacionInicialLng
  61.            End If
  62.  
  63.  
  64.            Do
  65.                v = k
  66.                n = Numchars
  67.                Do
  68.                    x = (v Mod p_Sizealfabeto)
  69.                    Clave(n) = p_Alfabeto(x) ' convertir el byte a char.
  70.                    v \= p_Sizealfabeto ' división entera.
  71.                    n -= 2
  72.                Loop While (n >= 0)
  73.                ' USAR la clave desde aquí
  74.                ' llamada a FuncionX(Clave)
  75.                k += 1
  76.            Loop While (k < s_MaxPermutaciones)
  77.        End With
  78.  
  79.        Crono = ((TimeOfDay.Ticks - Crono) / 10000000)  ' ticks a la hora actual, menos los de comienzo= ticks invertidos en la tarea.
  80.        MessageBox.Show(Crono.ToString & vbCrLf & s_MaxPermutaciones.ToString)
  81.    End Sub
  82. End Class
  83.  

- La clase es bien sencilla, al inicio la declaración de variables, el alfabeto y el tamaño del mismo, por razones de rendimiento es preferible copiarlos a esta... Para que quede claro se deja constancia del tipo de datos que VB.NET son, para facilitar la conversión a otro lenguaje (tal como allí se designe el tipo equivalente).
- Luego viene la clase anidada (para generar el alfabeto).
- Detrás viene definida una estructura con los siguientes 4 elemntos:
----- La instancia de clase del alfabeto creado previamente y que se usará. éste contiene dos cosas, el alfabeto (charSet) a usar y el tamaño de dicho alfabeto).
----- El tamaño de las claves que queremos generar
----- Un posible punto de inicio, para enumerar las claves (en forma de una clave (string). Esta parte no se ha implementado...
----- Un posible punto de inicio, para enumerar las claves (en forma de la enésima clave (número)).
- Finalmente el método para Enumerar (generar las permutaciones). Recibe como único parámetro, la estructura que se acaba de explicar.
Inicia el crono 8para calcular el tiempo invertido en generarlo) y acto seguido toma de la clase AlfabetotoUse, tanto el alfabeto como su tamaño, así una posterior modificación de dicha clase, mientras se está permutando, no afecta al trabajo en curso evitando errores...
Luego unas asignaciones y cáclulos elementales, tras lo cual viene finalmente el bucle de la enumeración.
Las permutaciones se consiguen cambiando la base numérica desde un valor decimal (base 10), a la base numérica cuyo valor es el tamaño del alfabeto... dicho valor se usa como el desplazamiento dentro del alfabeto para seleccionar el carácter con que se representa en dicha base numérica.

Y eso es todo lo que respecta a la clase... al término de la enumeración indica el tiempo transcurrido.

Queda el código de la interfaz de usuario... Se ha omitido en la interfaz la designación tanto de un alfabeto custom, como un alfabeto basado en el ASCII, definido por un punto de inicio y una cantidad de caracteres... (queda al esfuerzo de los interesados, modificar y/o ampliar características).
Dado lo sencillo de la interfaz, las explicaciones dadas y el código a continuación creo superfluo extenderme más... pero si alguien tiene alguuna duda, que pregunte.


Código
  1. Public Class frm1 ' la ventana, formulario...
  2.    Dim alfa As cBaseNum.AlfabetoToUse
  3.  
  4.    Dim SizeAlfabeto As Short
  5.    Dim TipoAlfabeto As cBaseNum.AlfabetoToUse.CaracteresUsadosEnAlfabeto
  6.  
  7.  
  8.    ''' <summary>
  9.    ''' Por defecto, al inicio el alfabeto es A-Z (26 caracteres)
  10.    ''' </summary>
  11.    ''' <param name="sender"></param>
  12.    ''' <param name="e"></param>
  13.    ''' <remarks></remarks>
  14.    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  15.        TipoAlfabeto = cBaseNum.AlfabetoToUse.CaracteresUsadosEnAlfabeto.ALFABETO_AZ_UPPERCASE
  16.        SizeAlfabeto = 26
  17.    End Sub
  18.  
  19.    ''' <summary>
  20.    ''' Selección del tipo de alfabeto a usar
  21.    ''' </summary>
  22.    ''' <param name="sender"></param>
  23.    ''' <param name="e"></param>
  24.    ''' <remarks>Se han ligado los eventos de todos los checkbox a este método</remarks>
  25.    Private Sub CheckBox1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox1.CheckedChanged, CheckBox2.CheckedChanged, CheckBox3.CheckedChanged
  26.        TipoAlfabeto = 0 : SizeAlfabeto = 0
  27.  
  28.        If (CheckBox1.Checked = True) Then
  29.            TipoAlfabeto = cBaseNum.AlfabetoToUse.CaracteresUsadosEnAlfabeto.ALFABETO_09
  30.            SizeAlfabeto = 10
  31.        End If
  32.  
  33.        If (CheckBox2.Checked = True) Then
  34.            TipoAlfabeto = (TipoAlfabeto Or cBaseNum.AlfabetoToUse.CaracteresUsadosEnAlfabeto.ALFABETO_AZ_UPPERCASE)
  35.            SizeAlfabeto += 26
  36.        End If
  37.  
  38.        If (CheckBox3.Checked = True) Then
  39.            TipoAlfabeto = (TipoAlfabeto Or cBaseNum.AlfabetoToUse.CaracteresUsadosEnAlfabeto.ALFABETO_AZ_LOWERCASE)
  40.            SizeAlfabeto += 26
  41.        End If
  42.  
  43.        ' si se deseleccionó todo, por defecto será todo el rango ASCIIasigna
  44.        If TipoAlfabeto = 0 Then SizeAlfabeto = 256
  45.  
  46.        GroupBox1.Text = "Tamaño del diciconario: " & SizeAlfabeto.ToString
  47.    End Sub
  48.  
  49.    ''' <summary>
  50.    ''' Reunir todos los datos y llamar a la enumeración.
  51.    ''' </summary>
  52.    ''' <param name="sender"></param>
  53.    ''' <param name="e"></param>
  54.    ''' <remarks></remarks>
  55.    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
  56.        Dim datos As cBaseNum.PermutarDatosImprescindibles
  57.        Dim cad As New cBaseNum
  58.  
  59.        ' Reunir los parámetros en una estructura, único parámetro del método enuerar de la clase...
  60.        With datos
  61.            .Charset = New cBaseNum.AlfabetoToUse(TipoAlfabeto) ' construir el alfabeto
  62.            .LargoClaves = NumericUpDown1.Value ' tamaño de las claves a generar.
  63.            .PermutacionInicialLng = -1 ' cambiar si se quiere iniciar en una secuencia distinta de la primera.
  64.            .PermutacionInicialStr = ""  ' no se ha implmenetado en la clase el inicio dado una clave concreta...
  65.        End With
  66.  
  67.        cad.Enumerar(datos)
  68.        MessageBox.Show("Finalizada la enumeración.")
  69.    End Sub
  70. End Class
  71.  

Como se puede apreciar, no se incluído ningún método complejo, ni nada especial que impida entender el código aún sin tener idea de VB.NET.

--------------------

Mañana saco un tiempito, y paso con el algoritmo-2, hice 3 versiones (piondré uno de cada vez), cada uno con sus características, para dar riqueza de experiencia y aprendizaje...
50  Foros Generales / Dudas Generales / Re: comenzar tarde en: 11 Mayo 2017, 02:36
Para aprender a programar no importa la edad... si uno está abierto a aprender, aprende. Si uno está cerrado, todo sonará a chino.

Yo te señalaría que en función del S.O. que tengas elijas un lenguaje adecuadamente implantado en dicha plataforma...
Por ejemplo si tienes Windows, te recomendaría .NET. Si partes de una base nula, mejor Visual Basic que C#. En cambio si tienes por ejemplo Linux, tirar por Phyton sería muy buena opción... Y en un punto medio a ambas plataformas, te diría Java... ahora tu decide.
Páginas: 1 2 3 4 [5] 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ... 35
Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines