| |
|
621
|
Programación / Programación Visual Basic / Re: leer datos en archivo secuencial
|
en: 27 Noviembre 2021, 02:02 am
|
Pues vaya M13RD@ de 'antivirus'... solo contiene los ficheros del proyecto más el fichero de ejemplo que desde luego no es un ejecutable. Subirlo a otro lado, no creo que solvente el asunto... el fichero zip es el mismo, quien lo detiene es ese tonto-antivirus (no la web), que desde luego parece inútil. Mira de desactivar el antivirus ese (eso es de vodafone, no?) , descárgalo y luego si quieres puedes pasarlo por virustotal, pero vamos con abrir el zip, se ve que no contiene nada 'malicioso'. No olvides volver a activar ese antivirus si lo encuentras útil... En esta pagina te viene cono activarlo y desactivarlo: https://www.adslzone.net/operadores/vodafone/vodafone-secure-net/¿Por lo que leo (un vistazo rápido) es para móviles, porqué no lo descargas desde el PC?. p.d.: Me edito... Si en cualquier momento queremos desactivar el servicio, desde cualquier dispositivo 1 abrimos una ventana de nuestro navegador favorito, 2 pulsamos sobre el icono de Vodafone Secure Net, seleccionamos el botón de ajustes 3 y en la parte inferior de la página 4 pulsamos sobre la opción Desactivar.
|
|
|
|
|
622
|
Programación / Programación Visual Basic / Re: leer datos en archivo secuencial
|
en: 26 Noviembre 2021, 23:27 pm
|
tu trabajas con funciones , me has cambiado la manera de trabajar, tengo que seguir con lo que dices tu, yo ya no puedo trabajar con lo que hacia yo.
Ok... Ayer al final no me puse con él. ...pero lo acabo de terminar ahora y probar por encima... he cambiado algunos detalles (por ejemplo el orden en que muestran los campos en el listbox) y corregido algunas diferencias (por ejemplo, en el registro el numero de ticket estaba definido como entero, y la busqueda suponía en long, lógicamente no lo encontraría de esa manera). Te comparto del proyecto completo... incluye un fichero de ejemplo con algunos registros guardados. Lo modificas a tu necesidad, pero recuerda que si cambias la estructura del registro (type...), elimina el fichero y crea uno nuevo. Por ejemplo el campo 'producto' es demasiado brece (12 caracteres), si pongo 'Destronilladores' no cabe ni mucho menos 'juego de ...' 30-40 caracteres, estaría bien. Nota que la búsqueda por artículo exige que sea exacta (salvando la capitalización), sería adecuado modificarlo o añadir un parámetro para localizar por similitud (like, o contiene parcialmente...). Enlace de descarga: https://workupload.com/file/AHRpXupVQQz 11Kb. aprox. descomprimido 35.5kb, aprox. No hay mucho que explicar, revisa el código ejecutándolo paso a paso, para entender cada cosa, céntrate cada vez en una sola cosa... manejo de ficheros, lectura/escritura de datos, edición de un registro, validaciones, etc...  Si necesitas alguna aclaración, pregunta.
|
|
|
|
|
623
|
Programación / Programación Visual Basic / Re: leer datos en archivo secuencial
|
en: 25 Noviembre 2021, 20:05 pm
|
|
Esperaba que pudieras deducir que se trata de botones...
No es necesario poner código para los optionbuttons, además deben formar un array, esto es deben tener el mismo nombre pero uno con índice 0 y otro 1, así su índice ya refiere su valor sobre el método de pago.
La función 'getmetodopago', si te fijas bien en lo que hace, simplemente devuelve un string, en base al valor recibido... eso solo se usa para convertir el valor del método de pago en el string, que luego se va a introducir al listbox (pasar al listbox, 0 ó 1, no dice nada útil ni comprensible).
Creo que estás más verde aún de lo que parece en cuanto al dominio no solo del lenguaje sino de claridad de ideas respecto de la programación.
Normalmente 'el conocimiento' y 'la inteligencia' (las capacidades intelecturales) es algo innato, que al programar uno debe saber 'traducir' y respecto del lenguaje es algo que sí o sí uno debe aprender desde cero (esto pasa con cualquier nuevo lenguaje que uno quiera aprender). Quiero decir que la programación no es un invento, sino el resultado del intelecto, aplícalo y la programación será más fácil, si partes de la idea de que la programación es un invento de alguien, entonces te será difícil aplicarte, porque parece exigir aprender o ponerte en el pellejo de quien 'lo inventó'. Eso es cierto para el lenguaje, que suele obedecer en ocasiones al capricho de su diseñador aunque en buena medida es el resultado de meditar y madurar ideas... Si intentas aplicar lógica con inteligencia a la programación, el resto sólo depende de la profundidad en que conozcas el lenguaje en el que pretendes escribirlo.
Bien, respecto del asunto, en realidad anoche lo dejé más avanzado, de lo que te envié, en un momento, simplemente me pareció que era preferible copiarlo y guardarlo para enviártelo así y desde ahí intentaras por tu cuenta a modo de ejercicio completar lo que faltara, para ver como lo resolvías. Los botones de la interfaz, por ejemplo los moví a un menú, los textbox a una ventana para editar el registro, los valores de búsqueda a otra ventana para lo mismo, definir los parámetros de búsqueda, cambié alguna cosa más... y deje para hoy solamente la activación y desactivación de los botones (ahora en el menú), según correspondan... lo terminaré más tarde, después de cenar. Te comentaré por aquí por encima, y subiré copia a alguna página de descarga...
|
|
|
|
|
624
|
Programación / Programación Visual Basic / Re: leer datos en archivo secuencial
|
en: 24 Noviembre 2021, 23:55 pm
|
La instrucción LenB(variable), devuelve la cantidad de bytes que contiene esa variable, así como Len(string) devuelve la cantidad de caracteres (no necesariamente se corresponde con la cantidad de bytes). en cualquier caso, cuando tengas dudas, posicionar el cursor encima de la instrucción (o cualquier parte de la sintaxis de vb6), pulsa la tecla F1 y te lleva a la ayuda, donde tes explica su cometido y puede incluso contener algún ejemplo. Por cierto... esa función tiene un pequeño error del que me acabo de dar cuenta, te comento por encima: Lo habitual es que al comienzo de ficheros con un determinado formato, exista una cabecera (de tamaño fijo generlamente o al menos conocido antes de escribir lo que venga detrás), en este caso la cabecera está compuesta por un único dato: 'NumRegistros', que al ocupar 4 bytes (del long de vb6), debe añadirse para calcular la posición absoluta de lectura/escritura de comienzo de u registor dado, es decir el primer registor debe comenzar en la posición 5 (vb6 considera que un fichero comienza siempre en la posición 1). Private Sub PosicionarRegistro(ByVal Numregistro As Long) If (Abierto = True) Then Seek (Canal), (5 + ((Numregistro-1) * LenB(reg1))) End If End Sub
-------------------------------------------------------------------------- Tu segunda duda: para activar o desactivar ... lo que proceda Lo razonable es que hayas elementos en la interfaz que estén 'sincronizados' con determinados estados... por ejemplo el botón 'guardar' registro debería estar desactivado mientras no se haya abierto el fichero. Si ni siquiera existe un fichero, es adecuado que esté habilitado un botón 'Crear nueva Factuación' (imagina por ejemplo un fichero por cada mes), que cierre el previo, vacíe el listado y los textbox, crea y abre un nuevo fichero y entonces activa los botones de añadir registro y buscar y cerrar, etc... Siempre se puede añadir una comprobación dle tipo: si Abierto=true luego ... fin si En el código (por ejemplo) del botón guardar registro, peor lo ideal es que si no se puede guardar, ese btón no estuviere activo. --------------------------------------- ...me edito, para ponerte el código... estará sin terminar al completo y sin provar ya que va siendo tarde, mira a ver si completas lo que falta (el código de los botones) y alguna pequeña función... Nota que te pongo todo de nuevo, porque he cambiado alguna cosa... la función abrir, ahora debe abrir bajo dos condiciones, cuando se lee un fichero existente y cuando se pretende crear un nuevo fichero (que no debe existir)... Las funciones añadidas, están al final... falta el código de los botones y alguna función más para completarlo. Abajo pongo una capturas de como se vería la interfaz y vale por hoy. Private Enum MetodosDePago PAGO_AL_CONTRADO = 0 PAGO_CON_TCREDITO = 1 End Enum Private Type RegCompra NumTicket As Integer ' 1 FechaCompra As Date ' 3 MetodoDePago As Byte ' 11 Alineacion As Byte ' 12 nada solo hace que el registro sea una cantidad par, para ser más efectivo en lecturas Producto As String * 12 ' 13 PrecioUnidad As Single ' 25 Cantidad As Integer ' 29 SubTotal As Single ' 31 End Type ' total: 34 bytes por registro Private Const DIR_COMIENZO_REGS As Long = 9 ' 1+4+4 Private NumRegistros As Long Private AutonIncRegs As Long ' Private Canal As Integer ' Número de canal de comunicación con el fichero. Private reg1 As RegCompra ' para leer registros Private reg2 As RegCompra ' para escribir registro, así diferenciados, será más difícil equivocarnos Private Sub ComNuevaFacturacion_Click() If (Len(TxtFile.Text) > 0) Then Call CrearNuevaFacturacion(TxtFile.Text) End If End Sub Private Sub ComAbrirFacturacion_Click() Form2.Show 1 If (Len(Form2.File) > 0) Then If (LeerFacturacion(App.Path & "\" & Form2.File) = True) Then Call Activar(True) Else Call Activar(False) End If End If End Sub Private Sub ComBuscar_Click() ' End Sub Private Sub ComEditarRegistro_Click() ' End Sub Private Sub ComGuardarRegistro_Click() ' End Sub Private Sub ComRetirarRegistro_Click() ' End Sub Private Sub ComSalir_Click() ' End Sub Private Sub List1_Click() If (Abierto = True) Then Call PosicionarRegistro(List1.ListIndex + 1) Get #Canal, , reg1 Call TrasferirRegToTextbox(reg1, vbTab) End If End Sub ' ------------ Fin interfaz ------------------ Private Function LeerFacturacion(ByRef Ruta As String) As Boolean Dim k As Integer If (Abrir(Ruta) = True) Then Get #Canal, 1, NumRegistros For k = 1 To NumRegistros Get #Canal, , reg1 Call List1.AddItem(SerializarRegistro(reg1)) Next ' Ahora si se quiere puede leerse de nuevo el primer registro para transferirlo a los textbox... List1.ListIndex = 0 ' para ello delegamos en el código que pondremos al listbox... End If End Function Private Sub TrasferirRegToTextbox(ByRef R As RegCompra) With R txtNumTicket.Text = .NumTicket txtFechaComprar.Text = CStr(.fecha) optMetodoPago(.MetodoDePago).Value = True ' 2 controles option con indices 0 y 1 'cheMetodoPago.value = .MetodoDePago ' también vale un checkbox, que cambie su 'caption' según su valor, alternando entre 'Pago al contado' o 'Pago con Tarjeta de crédito'. txtProducto.Text = .Producto txtPrecioUnidad.Text = CStr(.PrecioUnidad) txtCantidad.Text = CStr(.Cantidad) txtSubtotal.Text = CStr(.SubTotal) End With End Sub Private Sub PosicionarRegistro(ByVal Numregistro As Long) If (Abierto = True) Then Seek (Canal), (DIR_COMIENZO_REGS + ((Numregistro - 1) * LenB(reg1))) End If End Sub Private Function SerializarRegistro(ByRef Registro As RegCompra, ByVal Separador As String) As String With Registro SerializarRegistro = CStr(.NumTicket) & Separador & CStr(.FechaCompra) & _ Separador & GetMetodoPago(.MetodoDePago) & Separador & .Producto & _ Separador & CStr(.Cantidad) & Separador & CStr(.PrecioUnidad) & Separador & CStr(.SubTotal) End With End Function Private Function GetMetodoPago(ByVal Metodo As MetodosDePago) As String If (Metodo = PAGO_AL_CONTRADO) Then GetMetodoPago = "Contado" Else GetMetodoPago = "T. Credito" End If End Function Private Function ExisteFichero(ByRef Ruta As String) As Boolean Dim j As Integer, File As String j = InStrRev(Ruta, "\") If (j > 0) Then File = LCase$(Right$(Ruta, Len(Ruta) - j)) ExisteFichero = (LCase$(Dir(Ruta, vbNormal)) = File) End If End Function ' Abre un fichero que YA EXISTE: Cuando se solicita leer la facturación de uno. ' Abre un fichero que NO EXISTE: Cuando se trata de crear una nueva facturación. Private Function Abrir(ByRef Ruta As String, Optional ByVal NoDebeExistir As Boolean = False) As Boolean If (Abierto = True) Then Call Cerrar If (ExisteFichero(Ruta) = False) Then If (NoDebeExistir = False) Then Exit Function End If Canal = FreeFile On Error GoTo FalloApertura Open Ruta For Binary As #Canal FalloApertura: If (Err.Number > 0) Then Call MsgBox("Error al intentar abrir el fichero en la ruta:" & vbCrLf & Ruta & vbCrLf & Err.Description, vbInformation, "Error de apertura:") Err.Clear Else Abrir = True End If On Error GoTo 0 ' hay que desactivar el controlador de errores, si no, cualquier error posterior cae en este interceptador (si es el último activo)... End Function Public Property Get Abierto() As Boolean Abierto = (Canal > 0) End Property Private Function Cerrar() Close #Canal Canal = 0 NumRegistros = 0 ' desactivar de la interfaz lo que proceda... End Function ' ------------------------------------------------- ' -------- NUEVO DESDe AQUI --------------- '-------------------------------------------------- ' Index refiere al enésimo registor en el fichero. ' Si es -1 refiere al último, lo adecuaod cuando se añade. ' Si es entre 1 y NumRegistros, señala que es un registro que se ha editado... Private Sub GuardarRegistro(ByRef R As RegCompra, Optional ByVal Index As Long = -1) If (R.NumTicket = 0) Then AutonIncRegs = (AutonIncRegs + 1) R.NumTicket = AutonIncRegs End If ' If (Index = -1) Then NumRegistros = (NumRegistros + 1) Index = NumRegistros End If Call PosicionarRegistro(Index) Put #Canal, , R ' Guarda el registro Put #Canal, 1, NumRegistros ' Guarda la cantidad de registros Put #Canal, , AutonIncRegs ' Guarda el valor de autoincrmeento (es un valor único). End Sub Private Function CrearNuevaFacturacion(ByRef NombreFile As String) As Boolean Dim Ruta As String Ruta = App.Path & "\" & NombreFile If (Abrir(Ruta, True) = True) Then NumRegistros = 0: AutonIncRegs = 0 Put #Canal, 1, NumRegistros ' Guarda la cantidad de registros Put #Canal, , AutonIncRegs ' Guarda el valor de autoincrmeento (es un valor único). CrearNuevaFacturacion = True Else MsgBox "Parece que el fichero que intenta abrir ya existe, elija otro nombre (o bien ocurrió un error)..." End If End Function ' Numreg: Permite seguir buscando más artículos a partir del previo que se encontró... Private Function BuscarArticulo(ByRef Producto As String, Optional ByRef NumReg As Long = 0) As Boolean Dim k As Long, ptr As Long, inc As Long, Articulo As String * 12 If (NumReg < NumRegistros) Then NumReg = (NumReg + 1) If (NumReg > 1) Then Call PosicionarRegistro(NumReg) ptr = Seek(Canal) + 12 Else ptr = (DIR_COMIENZO_REGS + 12) ' Dir de comienzo de registros + desplazamiento al campo soliicitado. End If Producto = LCase(Producto) inc = LenB(reg1) For k = NumReg To NumRegistros Get #Canal, ptr, Articulo If (LCase$(Articulo) = Producto) Then Get #Canal, ptr - 12, reg1 BuscarArticulo = True Exit For End If ptr = (ptr + inc) Next NumReg = k End If End Function ' En cada fichero cada compra tiene un numero de ticket único (no hay dos repetidos, como si puede pasar con el nombre del artículo). Private Function BuscarTicket(ByVal Ticket As Long) As Boolean Dim k As Long, ptr As Long, inc As Long, nTicket As Long ptr = DIR_COMIENZO_REGS ' Dir de comienzo de registros + desplazamiento al campo soliicitado=0. inc = LenB(reg1) For k = 1 To NumRegistros Get #Canal, ptr, nTicket If (LCase$(nTicket) = Ticket) Then Get #Canal, ptr, reg1 BuscarTicket= True Exit For End If ptr = (ptr + inc) Next End Function
Yo elegiría un control flexgrid en vez de un listbox, que ya tiene sus columnas y tal, pero es más complejo de manejar para empezar... Nota que la interfaz de momento la dejo así, solo para que puedas captar todos los detalles que contiene. En realidad cosas como los textbox deben ir a una ventana aparte donde se editen o creen... pero así no te hago esperar si ves todo lo que contiene e intentas por tí mismo completarlo. 
|
|
|
|
|
625
|
Programación / Programación C/C++ / Re: Creacion Matriz nxn Automatica
|
en: 24 Noviembre 2021, 15:54 pm
|
|
Intenta conseguir primero imprimir el array de nxn... Si lo consigues entonces podrás centrarte luego en resolver la cuestión de los asteriscos.
Inicialmente necesitarás dos bucles anidados. El primer bucle recorrer las filas (actúa verticalmente) El bucle interno recorre las columnas (actúa horizontalmente). Es este último el que hace el trabajo de impresión. Hay dos formas elementales de resolverlo: Primero conviene centrarse en la más simple:
- El bucle externo recorre las n filas desde 1 (ó desde 0 a n-1). - Internamente, la solución más sencilla-evidente es escribir dos bucles. ---- El primer de esos internos escribe los valores hasta el asterisco. ------- Cuántos valores debe escribir entonces este bucle?. La primera fila 1 menos de 'n', las siguientes filas 1 menos que la fila anterior... es decir hay una resta, entonces qué tal si antes de entrar a ese bucle, calculamos ese valor?. ---- Cuando sales del bucle, imprime los asteriscos. ---- el segundo bucle interno escribe los valores que vienen a continuación de los asteriscos. ------- Cuántos valores debe escribirse tras los asterisocs?. La primera fila 0, las siguientes filas uno más que la anterior... es decir es una suma, entonces que tal si al salir de este bucle (puesto que empieza en 0), calculas ese valor para la próxima vez?. Para no incurrir en equívocos, usa 3 variables contadores (n,j,k) uno para cada bucle, como límite del recorrido así no te confundes...
Esta es la forma más simple para un principiante. Una vez que lo logres, puedes intentar meter en el primer bucle lo que le sigue. Pero si no lo logras, al menos el previo podrás entregarlo en clase.
...es decir imprimir los asteriscos y los valores a su derecha eliminando así el segundo bucle (interno), se resuelve en solo uno interno con la sentencia if...else... aunque sigas teniendo las variables n,j,k.
|
|
|
|
|
626
|
Sistemas Operativos / Windows / Re: Ordenador portatil o de mesa con windows 11 alrededor de 350€?
|
en: 24 Noviembre 2021, 01:33 am
|
|
Qué pesado con windows 11...
Olvida windows 11, durante 1 año, que salga y corrijan errores, y cuando tenga cierta estabilidad, vale que te intereses. alguien con tus capacidades no está para trastear con novedades que ante cualquier eventualidad no sabes que hacer más que hacer 1000 preguntas que aunque sean respondidas no sabrás aplicar.
Por otro lado, por qué crees que va a haber un portátil que calce windows 11 que sea 'potente' por 350 euros?.
El sistema operativo siendo nuevo, recién horneado y a falta de aromas y envases, valdrá no menos de 150euros... un procesador potente (para jugar es necesario), tampoco valdrá menos de 100-150 euros (tirando por lo bajo) y aún falta el resto del equipamiento, unidad de almacenamiento, memoria, tarjeta gráfica y pantalla también tienen un coste nada despreciable... puede que para cuando esté disponible, por 500 euros consigas comprar un modesto portátil con windows 11.
...y ahora con la 'escasez' de microchps, acabarán subiendo los precios... esperemos que no se acaben duplicando.
|
|
|
|
|
627
|
Programación / Programación Visual Basic / Re: leer datos en archivo secuencial
|
en: 24 Noviembre 2021, 01:09 am
|
' Nuevo registro: Private Sub Command5_Click() ' recuperar el dato. Open App.Path & "\Numero1.txt" For Input As #1 Do While Not EOF(1) Input #1, orden Loop Close #1
Esto no tiene sentido... Si intento buscarle uno, diría que intentas llegar a la última entrada, pero... el código en el botón guardar, no lo confirma, porque el guardado de datos tiene formato, luego ahí en ese bucle, lo único que haces es recorrer a saltos de 2 bytes (los bytes de un integer de vb6) con cada lectura... hasta llegar al final del fichero, pero ni siquiera hay garantías de eso, si el fichero tiene bytes impares. Open thj For Input As #1 Input #1, orden Txtnum.Text = orden Input #1, fecha Label4.Caption = fecha Input #1, hora Label5.Caption = hora Input #1, contado Input #1, credito Input #1, cedu1, nom1 txtCedula1.Text = cedu1 txtNombre1.Text = nom1 While Not EOF(1) Input #1, cantidad, producto, preciox, subtot cant.Text = cantidad prod.Text = producto Precio.Text = preciox subtotal.Text = subtot List1.AddItem cantidad & vbTab & producto & vbTab & preciox & vbTab & subtot Wend Close #1
Aquí, aunque está mejor tampoco es óptimo.... Si el fichero contiene pongamos 1000 registros, parece que todos están obligados a rescribir contínuamente ciertos textbox... Además, operando con registros, lo adecuado es usar una estructura, para escribir y leer de una sola vez cada registro... private type RegCompra NumTicket as integer FechaCompra as date Contado as string * ??? Credito as string * ??? Producto As String * 12 PrecioX As String * 8 ' por qué un string?. _Sería adecuado un single Cantidad as integer SubTotal As Double ' no requiere un dobule, basta con un single, no vas a realizar cantidades astronómicas que escapen a un single. end type
- Por qué llamarlo 'orden' si es el ´numero del ticket?. - Por que guardar a fichero la fecha y luego la hora, cuando la fecha guarda todo?. - Qué es credito y qué contado?. el método de pago?. Si es así crea una enumeracion: Private Enum MetodosDePago PAGO_AL_CONTRADO = 0 PAGO_CON_TCREDITO = 1 End Enum
Si 'credito es por ejemplo el número de la tarjeta de crédito, entonces si puede ser un string, en ese caso reserva una cantidad fija de caracteres. En ficheros con VB6, al guardar strings, hay 3 opciones, la más cómoda es definir una cadena de tamaño fijo, la otra es escribir tu mismo a fichero al momento de escribir el string, un integer indicando la cantidad de caracteres de esa cadena (que más adelante se usará para saber cuanto leer), la 3 opción es abrir el fichero 'for input', en cuyo caso vb6 se encarga previo a cada parámetro (incluido arrays), anteponer el tipo de dato guardado, es decir una cabecera donde se incluye el tipo e info adicional (si se precisa), para saber cuantos bytes leer con cada campo, esto lo hace más complejo, no tienes control de ello y acaba resultando lento... No es preciso guardar a fchero los textos esos de 'gracias por su visita' ni otros textos, tan solo los datos... tu luego tendrías en todo caso una función llamada 'ImprimirFactura(registro)' que crea ese reporte textual formateando los datos de un registro, por ejemplo para imprimirlo con la impresora (para practica, basta imprimirlo en una ventana aparte). Mi consejo es abrirlo 'for binary', en este modo tú tienes el control de cada byte, no se añade nada extra que tu desconozcas, lo que te da un control pleno sobre el contenido del fichero... además es más rápido al no tener que verificar cada cosa que se lee o escribe. Y tratándose de registros es conveniente que todos tengan el mismo tamaño, por lo que conviene que cada string en el resgistro tenga un tamaño fijo. Cuando se usa variable string de tipo fijo, utiliza exactamente esos caracteres y ninguno más... Entonces manejar tu fichero podría ser así: Private Enum MetodosDePago PAGO_AL_CONTRADO = 0 PAGO_CON_TCREDITO = 1 End Enum Private Type RegCompra NumTicket As Integer ' 1 FechaCompra As Date ' 3 MetodoDePago As Byte ' 11 Alineacion as byte ' 12 nada solo hace que el registro sea una cantidad par, para ser más efectivo en lecturas Producto As String * 12 ' 13 PrecioUnidad As Single ' 25 Cantidad As Integer ' 29 SubTotal As Single ' 31 End Type ' total: 34 bytes por registro Private Canal As Integer ' Número de canal de comunicación con el fichero. Private NumRegistros As Long Private reg1 As RegCompra ' para leer registros Private reg2 As RegCompra ' para escribir registro, así diferenciados, será más difícil equivocarnos ' Leer Factura Private Sub Command7_Click() If LeerFacturacion("poner aqui tu ruta") = True Then ' Activar en la interfaz lo que proceda Else ' desactivar de la interfaz lo que proceda End If ' para activar o desactivar es preferible tener una función que reciba un buleano y en base a ello activa o desactiva cada cosa que proceda... ya que también se llamaría desde 'cerrar' End Sub Private Function LeerFacturacion(ByRef Ruta As String) As Boolean Dim k As Integer If (Abrir(Ruta) = True) Then Get #Canal, 1, NumRegistros For k = 1 To NumRegistros Get #Canal, , reg1 Call List1.AddItem(SerializarRegistro(reg1)) Next ' Ahora si se quiere puede leerse de nuevo el primer registro para transferirlo a los textbox... list1.listindex = 0 ' para ello delegamos en el código que pondremos al listbox... End If End Function Private Sub TrasferirRegToTextbox(ByRef R As RegCompra) With R txtNumTicket.Text = .NumTicket txtFechaComprar.Text = CStr(.fecha) optMetodoPago(.MetodoDePago).Value = True ' 2 controles option con indices 0 y 1 'cheMetodoPago.value = .MetodoDePago ' también vale un checkbox, que cambie su 'caption' según su valor, alternando entre 'Pago al contado' o 'Pago con Tarjeta de crédito'. txtProducto.Text = .Producto txtPrecioUnidad.Text = CStr(.PrecioUnidad) txtCantidad.Text = CStr(.Cantidad) txtSubtotal.Text = CStr(.SubTotal) End With End Sub Private Sub PosicionarRegistro(ByVal Numregistro As Long) If (Abierto = True) Then Seek (Canal), (1 + ((Numregistro-1) * LenB(reg1))) End If End Sub Private Function SerializarRegistro(ByRef Registro As RegCompra, ByVal Separador As String) As String With Registro SerializarRegistro = CStr(.NumTicket) & Separador & CStr(.FechaCompra) & _ Separador & GetMetodoPago(.MetodoDePago) & Separador & .Producto & _ Separador & CStr(.Cantidad) & Separador & CStr(.PrecioUnidad) & Separador & CStr(.SubTotal) End With End Function Private Function GetMetodoPago(ByVal Metodo As MetodosDePago) As String If (Metodo = PAGO_AL_CONTRADO) Then GetMetodoPago = "Contado" Else GetMetodoPago = "T. Credito" End If End Function Private Function ExisteFichero(ByRef Ruta As String) As Boolean Dim j As Integer, file As String j = InStrRev(Ruta, "\") If (j > 0) Then file = LCase$(Right$(Ruta, Len(Ruta) - j)) ExisteFichero = (LCase$(Dir(Ruta, vbNormal)) = file) End If End Function Private Function Abrir(ByRef Ruta As String) As Boolean If (Abierto = True) Then Call Cerrar If (ExisteFichero(Ruta) = True) Then Canal = FreeFile On Error GoTo FalloApertura Open Ruta For Binary As #Canal FalloApertura: If (Err.Number > 0) Then Call MsgBox("Error al intentar abrir el fichero en la ruta:" & vbCrLf & Ruta & vbCrLf & Err.Description, vbInformation, "Error de apertura:") Err.Clear Else Abrir = True End If On Error GoTo 0 ' hay que desactivar el controlador de errores, si no, cualquier error posterior cae en este interceptador (si es el último activo)... End If End Function Public Property Get Abierto() As Boolean Abierto = (Canal > 0) End Property Private Function Cerrar() Close #Canal canal = 0 NumRegistros = 0 ' desactivar de la interfaz lo que proceda... End Function Private Sub List1_Click() If (Abierto = True) Then Call PosicionarRegistro(List1.ListIndex + 1) Get #Canal, , reg1 Call TrasferirRegToTextbox(reg1, vbtab) End If End Sub
Nota que cuando la apertura Falla, deben desactivarse x botones para no incurrir en errores, como el de 'nuevo registro-añadir', etc... Con esto abrimos y leemos cada registro, se transfiere al listbox (que ahora tiene más columnas, una por cada campo de la estructura-registro), y el primero se transfiere a los textbox. Nota como el botón para leer el fichero separa la operatoria de leer el fichero (que delega en una función) del resto de lo que tiene que hacerse en la interfaz, que se opera ahí, aunque también puede delegarse a otra función, porque al cerrar el fichero igualmente deben desactivarse ciertos controles de la interfaz. Tu código tiene mucho para comentar... pero no me apetece ahora señalarte cada cosita... Se me hace tarde, mañana si te place te pongo lo que correspondería para añadir un nuevo registro y guardarlo a fichero... incluso para buscar un determinado registro. Mientras échale un ojo al código...
|
|
|
|
|
629
|
Seguridad Informática / Hacking / Re: AYUDA!! Fraude en el correo del trabajo! ALGUIEN ME AYUDA!?
|
en: 23 Noviembre 2021, 22:56 pm
|
|
Mi consejo es que las facturas, aunque te las envíen por correo electrónico, el número de cuenta no conste ahí, que te lo pasen por una llamada telefónica, especialmente cuando la cuenta del banco no coincida con la cuenta que debieras tener guardada de la última vez. Es decir cualquier cambio de cuenta bancaria, reclama confirmación telefónica antes de realizar la transferencia, para evitar precisamente estos fraudes, que como ves, resulta muy difícil de esclarecer (y va a más a futuro).
Te pueden interceptar el correo, y quizás alguna aplicación del propio tf. pero una llamada de tf. donde tu ya conoces el número y la voz de tu interlocutor, es evidentemente más difícil. Si te ponen una 'secretaria nueva' alegando que 'el jefe está ocupado y me ha dejado este encargo', entonces toca preguntarles algo personal que solo alguien que trabaje en esa empresa en cierta posición esté en posición de saberlo, la secretaria del jefe también. Pero vamos llamando al interesado puede confirmarte si ese es o no su número de cuenta y banco...
Respecto de tu transferencia, que sepas que tienes hasta x días (no recuerdo si 3,7,10 ó incluso 15 días, deberías consutarlo con tu banco para otra ocasión, y depende del país obviamente) para volver atrás la transferencia, alegando precisamente en la cuenta a la que hiciste la transferencia no es la cuenta del destinatario legítimo, es decir al tiempo ese dinero devuelto se debe transferir a la verdadera cuenta del auténtico destinatario (eso evita que el banco entienda que estés cometiendo una irregularidad con tus intenciones, de hecho conviene explicarlo bien al director de la sucursal). Yo lo he hecho alguna vez... Eso supone que incluso aunque el destinaario falsificado no tuviera dinero en 'su cuenta' le queda un agujero deudor. En cualquier caso, si interpusiste denuncia ante la policía es de suponer que les diste ese número de cuenta al que hiciste la transferencia y evidentemente, tendrá una persona detrás... aunque es habitual que un delincuente cibernético, además utilice la cuenta también de otro, para uqe le hhagas ese ingreso y el retirarlo por cajero, sin que el auténtico dueño de esa cuenta se dé cuenta de ello (al menos en ese instante salvo casualidad de estar operando justo en esos instantes con su cuenta).
|
|
|
|
|
630
|
Seguridad Informática / Hacking / Re: Diccionario de Fuerza Bruta Tipo v2
|
en: 23 Noviembre 2021, 01:10 am
|
Estuve el sábado revisando si haya cambiado algo al respecto en la gramática y francamente es complicado de un vistazo rápido hacerse eco de ello... Básicamente obliga a leerse un tocho de cientos de páginas (siempre se puede acudir al índice para reducir al mínimo la lectura, pero es seguro que entonces se pierden ciertos detalles)... http://aplica.rae.es/grweb/cgi-bin/v.cgi?i=feRKWpxYQmpczbvbConsultando el último libro que compré de gramática ("La gramática descomplicada" de Alex Grijelmo, 2009 7ªEd.), que a fin de cuentas data del mismo año que "La nueva Gramática Española" del link citado, sobre las sílabas no dice nada especial que uno no sepa, de hecho hasta pasa de largo por su 'anatomía'. Es habitual considerar que las sílabas se componen de letras y luego saltar a los diptongos, triptongos e hiato, previo conocimiento de las vocales y consonantes. Lo cierto es que yo tengo en mi recuerdo que la sílaba se compone de 3 partes que es lo que expondré y de lo que he partido... el domingo me tomó algo más de una hora elaborar el esquema de la formación del que sin detallar a fondo, doy una simples pinceladas. silaba= [ataque] nucleo [coda] Sí, estos son los componente de la sílaba en base a su estudio, a la especificdad con la que se forman. Las palabras entre corchetes indica que son opcionales, pueden o no llevarlo, en cambio el núcleo es obligatorio. ataque= C[C] nucleo= V[ [V|H]V] coda= C[C]
C refiere a consonantes y V a vocales... esto de modo genérico, las reglas exactas las pondré más abajo. Que puede resumirse: - El ataque (cuando la sílaba lo lleva), se compone de 1 ó 2 consonantes. Otra forma de decirlo, puesto que puede o no llevar ataque es decir que hay 0, 1 o 2 consonantes. - El núcleo, viene a decir que siempre existe como mínimo una vocal, a veces lleva dos (diptongo) y a veces 3 (triptongo), la vocal del medio puede no existir o dicho de otro modo, estar remplazada por una 'H' que en ese caso es muda y por tanto se comporta como si fuera un vocal (so pena de insistir en considerarla consonante y complicar la estructura, que al final ofrece el mismo resultado, pero más complejo). - La coda cuando la lleva se compone de 1 u 2 consonantes, y como con el ataque considerando de forma absoluta que siempre se tiene, podemos asumir que entonces se compone de 0, 1 o 2 consonantes. Resumiendo: Esto es lo que recuerdo, sin embargo ayer (el domingo) mientras hacía todo el esquema se me vino a la cabeza algunas palabras (ejemplos de cada situación), donde la coda está formada por 3 consonantes, y cito los ejemplos que se me vinieron a la cabeza (es posible que existan más, pero basta que exista una para indicar que la 'teoría' no es correcta). Fi lms, gá ngster, tu ngsteno, te sts, nie tzschismo, se ltz, wa ttsHay que aclarar que originalmente ninguna de estas palabras es nativo-española, se puede asumir que las 'rarezas' en sílabas son casi en su totalidad de origen foráneo, es decir importadas del extranjero y al caso, si éstas dadas se hubiera importado siglos atrás, a buen seguro se escribirían distinto, posiblemente hubieran acabado mutando a: fi lmes, gá nster, tu nsteno, te ses, nie schismo, se lz, etc... Y que en mi opinión es hacia donde debiera haber mutado por indicación o regla gramatical a la sazón (que no existe, que yo sepa). Así como nos ha tocado vivir una época de empecinamiento purista absurdo, las palabras importadas tienden a mantenerse 'fieles al original en su idioma'... No son el único caso por el que la procedencia extranjera aporte nuevas sílabas (sin uso o apenas uso en el español, previamente): wagneriano, hamster, troll, etc... Hay que recordar que la letra 'w' es una letra importada, su sonido en español al final cae siempre en (v|b|gü), luego es realmente innecesaria y es un aborto propio de ese purismo absurdo (a ver si en esas otras lenguas han adoptado la 'ñ'). También hay codas extrañas procedentes de las lenguas precolombinas como 'tl' que se ve en 'náhuatl'. Quien sabe, a la vuelta de 100 años quizás hayan terminado su fase de mutación y todo lo que precisan es un rodaje y desgaste en el tiempo, que limen sus aristas y acaben como cantos rodados... como pasó con los términos procedentes del griego, latín,etc... que ya lo vemos con las perspectiva del tiempo. Claramente la cosa se complica cuando pasamos al detalle intrincado, los diptongos lo son con la combinación de ciertas vocales, de lo contrario forman un hiato que separa la sílaba y forma dos sonidos... para rematar el caso, las vocales tildadas se encargan en buena medida de definir diptongos: 'hay' es un diptongo, pero no 'ahí', que forma un hiato 'a-hí', incluso en triptongos, como en 'bahía' que ni es triptogo, ni diptongo 'ba-hí-a'. No solo tenemos la 'h' intercalada (que se puede resumir que actúa como una vocal muda), también tenemos que la 'y' puede comportarse como la vocal 'i', como en 'rey', pero mantiene su origen en cambio en 're yezuelo' como consonante aún procediendo de la misma raíz. También podemos hablar de las consonantes: - Si tomamos por ejemplo el ataque, no detrás de cualquier consonante aparece otra, por ejemplo: "'tp'-nucleo" es impronunciable en español, en cambio "'ps'-núcleo" se pronuncia obviando la 'p', como en psique, psicología... (sí una p muda se podría decir... que la gramática no señala por parte alguna, esto sucede básicamente con palabras importadas, incluso en la coda), muchas consonantes en cambio admiten como segunda consonante en el ataque la 'r' y la 'b', pero de nuevo una 'h' puede comparecer como segunda consonante (o tal vez considerada como primera vocal al ser muda), excepto que esa consonante sea precisamente la 'c' como 'cho-colate'. O la 'q' que no admite detrás de ella ninguna otra consonante. - La coda en cambio parece ser más restrictiva, algunas de ellas no se dan, aunque opcionalmente podrían añadirse, so pena de alargar la cantidad de sílabas generadas a cambio de no hallar palabras donde se den (luego aclaro esta diferencia), como la 'ñ', 'v' o 'w'. Algunas de ellas, en cambio aceptan la pronunciación, aún cuando procedan de otro idioma. No es fácil encontrar palabras en español acabadas en k y ciertas otras consonantes como: ro ck, crómle ch, su rf, tuare g, tuare gs, etc... e incluso no siendo algunas de nuestro idioma, si son pronunciables como: wa tts, Maxwe ll, sai ntPara finalizar estas pinceladas, considerando el tamaño de las sílabas, hay que decir que es difícil encontrar sílabas de más de 5 letras, pero ahí está 'truhán', una sola sílaba y palabra de 6 letras, dado que la coda (como se ha demostrado) admite hasta 3 consonantes, quien me quita que yo no inventare la palabra: 'truhángs-ter' (mezcla de truhán y gángster), como se ve 'truhángs' es de 8 letras y es perfectamente pronunciable incluso algo como 'ñhehizz' forma una sola sílaba, es pronunciable y tiene 2 'h'. Resumiendo. Limitarse a buscar solo las sílabas que contienen las palabras de nuestro diccionario, no reporta todas las sílabas posibles, es decir cualquiera puede crear una nueva palabra inexistente con cualquiera de la sílabas que aquí he generado. ...además el diccionario, aun conteniendo todas las palabras, no contiene las palabras de las conjugaciones de los verbos, que ofrecen muchas sílabas distintas que seguramente no constan en otras palabras (y que por tanto se perderían). Veo por tanto más útil generar una lista con todas las sílabas que sean pronunciables (considerando además, la posibilidad de coda de 3 consonantes, precisamente por ser pronunciables), de las que luego uno pueda filtrar para eliminar las que quiera, que crear una lista con las sílabas que contienen x palabras a las que puedan añadirse otras, pués esto siempre será más complicado que lo previo. Por ejemplo, aunque no es fácil encontrar sílabas que acaben con la coda 'zz', surge facilmente 'jazz', si esto es pronunciable, también lo será 'jozz' y 'pazz' u 'pezz' y tazz', etc... luego en la lista si uno quiere, puede filtrar las sílabas que acaben en 'zz', por considerar que realmente existen muy pocas, del mismo modo uno puede querer considerar eliminar las sílabas de 8 o 7 letras, dado que es complicado encontrar sílabas incluso de 6 letras que existan en palabras de nuestra lengua. Igualmente las sílabas tildadas, puede uno asimilarlas o hacerlas equivalente a la misma sílaba con la vocal sin tilde, especialmente si la idea de uno es usar (no crear) diccionarios para tirar de fuerza bruta y un sitio no admite letras tildadas como parte de sus contraseñas. Como digo que es más fácil eliminar ciertas sílabas existentes (en el fichero) que añadirlas si no estuvieran presentes, he considerado pués crear mejor una lista así. Ciertas condiciones me han parecido innecesarias, como añadir codas que empiecen por las consonantes :'ñ', 'v' y 'w', pero en cambio he dejado la posibilidad de acabar en 'q' y 'qs', por la simple razón de que puede pronunciarse como una 'c'... la infame: 'FAQS' (no la otra fucks), atestigua que es pronunciable aún cuando, sean siglas... Por supuesto cada cual puede tener su opinión al respecto y filtrar lo que desee o crear su propia lista desde cero si resulta que no se incluye cierta combinación que le parezca de interés... en ese caso esta explicación y la lista, pueden servirle de apoyo. Esto reporta algo más de 400.000 sílabas, cuando no creo que en entre las palabras existentes haya más de 5.000 sílabas. El resultado se obtiene en menos de 1 minuto. Nota que no me he metido a realizar una algoritmo expresamente para esto, pués ya tengo un programa de grafos para realizar análisis sintáctico basado en un conjunto de reglas, y opciones que puedo personalizar, y con ello puedo generar permutaciones con reglas muy dispares, simplemente programando el 'lenguaje' que suponen dichas reglas... Este es el conjunto de reglas finalmente en juego: 1 - Máximo número de caracteres = 8 2 - Peso minimo = 4 3 - Reglas de producción: #nucleoIni = a3:4|e3:4|y3:4|o3:4|u3:4 #nucleo = #nucleoIni|á3:1|é3:1|i3:1|í3:1|ó3:1|ú3:1|ü3:1 #hNucleo = h2:1|#nucleo #hrl= r2:1|l2:1|#hNucleo #diptongo= i4:1|u4:1|y4:1|h4:1 #triptongo= a4:1|á4:1|e4:1|é4:1|o4:1|ó4:1 #coda = b6:1|c6:1|d6:1|f6:1|g6:1|h6:1|j6:1|k6:1|l6:1|m6:1|n6:1|p6:1|q6:1|r6:1|s6:1|t6:1|x6:1|y6:1|z6:1
ataque = b1:1|c1:1|d1:1|f1:1|g1:1|h1:1|j1:1|k1:1|l1:1|m1:1|n1:1|ñ1:1|p1:1|q1:1|r1:1|s1:1|t1:1|v1:1|w1:1|x1:1|y1:1|z1:1|#nucleoIni b1= #hrl c1= #hrl d1= #hrl f1= #hrl g1= #hrl h1= #nucleo j1= #hNucleo k1= #hrl l1= l2:1|#hNucleo m1= #hNucleo n1= #hNucleo ñ1= #hNucleo p1= s2:1|#hrl q1= u3:4 r1= r2:1|#hNucleo s1= #hNucleo t1= #hrl v1= #hNucleo w1= #hNucleo x1= #hNucleo y1= #hNucleo z1= #hNucleo
c2= #nucleo h2= #nucleo l2= #nucleo r2= #nucleo s2= #nucleo
a3= #diptongo|#coda á3= #diptongo|#coda e3= #diptongo|#coda é3= #diptongo|#coda i3= #triptongo|u4:1|ú4:1|h5:1|#coda í3= #coda o3= #diptongo|#coda ó3= #diptongo|#coda u3= #triptongo|i4:1|í4:1|h5:1|#coda ú3= #coda ü3= e4:1|é4:1|i4:1|í4:1 y3= #triptongo|#coda
a4= #coda á4= #coda e4= y5:1|#coda é4= #coda i4= #coda í4= #coda o4= #coda ó4= #coda u4= #coda ú4= #coda h4= i5:1|í5:1|u5:1|ú5:1 y4=
a5= #coda á5= #coda e5= #coda é5= #coda i5= #coda í5= #coda o5= #coda ó5= #coda u5= #coda ú5= #coda h5= a5:1|á5:1|e5:1|é5:1|o5:1|ó5:1 y5=
b6= s7:1 c6= h7:1|k7:1|s7:1 d6= s7:1 f6= t8:1 g6= s7:1 h6= m7:1 j6= k6= h7:1 l6= f7:1|l7:1|m7:1|s7:1|t7:1 m6= p7:1|s7:1 n6= d7:1|c7:1|g7:1|s7:1|t7:1|z8:1 p6= s7:1 q6= s7:1 r6= d7:1|f7:1|s7:1 s6= h8:1|s7:1|t7:1 t6= c7:1|l8:1|s7:1|t7:1|z7:1 v6= s7:1 w6= s7:1 x6= y6= s7:1 z6= s7:1|z8:1
c7= h8:1 d7= s7:1 f7= g7= s7:1 h7= s7:1 k7= s7:1 l7= s7:1 m7= s7:1 p7= s7:1 s7= t7= s7:1|z8:1 z7= s7:1
h8= l8= t8= z8=
Las primeras reglas, se tratan como directivas, es decir cada otra regla de producción que la contiene en la parte derecha es remplaza por la equivalencia de aquella que aparece en la izquierda (el nombre de la regla). Esto es para 3 cosas, primero claridad, luego sencillez de revisión y tercero evitar errores al transcribir 40 veces los mismos valores. El programa por tanto preprocesa (también elimina las líneas en blanco) tales entradas de directiva y las convierte en:... bueno no veo necesario ponerlo todo, baste un ejemplo, para el ataque de 'r', 's' y 't': r1= r2:1|h2:1|a3:4|e3:4|y3:4|o3:4|u3:4|á3:1|é3:1|i3:1|í3:1|ó3:1|ú3:1|ü3:1 s1= h2:1|a3:4|e3:4|y3:4|o3:4|u3:4|á3:1|é3:1|i3:1|í3:1|ó3:1|ú3:1|ü3:1 t1= r2:1|l2:1|h2:1|a3:4|e3:4|y3:4|o3:4|u3:4|á3:1|é3:1|i3:1|í3:1|ó3:1|ú3:1|ü3:1 El texto a la izquierda es el nombre de la regla-nodo, lo que está a la derecha son cada una de las opciones que pueden seguir a ese nombre (exactamente como sucede en la descripción de las reglas de un lenguaje de programación). Es decir sus opciones son iteraciones que sustituyen al 'actual', y el tamaño del 'sustrato' (el stack.ToString), es la concatenación que se resuelve por recursión. Cada una de esas opciones son a su vez una regla, pero se adjunta con el 'peso' que supone añadir esa regla. Un nombre-regla, sin parte derecha equivale a un terminal. El límite de una silaba (condición de finales de los bucles), vienen dados por unas reglas simples: 1 - La regla es en sí misma un terminal (no admite que nada más se concatene detrás, acaba la recursión). 2 - La cantidad de caracteres máximos. También limita el final de la recursión, en este caso para no incurrir en desbordamiento. 3 - Final de iteración. La cantidad de 'hijo-nodos-opciones' que tiene la regla. 4 - De peso (en este caso condicionado a mínimo: (>= que) 4)... No es una sílaba si no reúne el peso mínimo. Esta última regla en realidad define la salida de datos, siempre que el peso sea 4 o mayor se ha obtenido una sílaba. Nota como al núcleo (a las vocales grupo3) se le ha dado un peso de 4. Esto impide que cuando se tome la una o dos consonantes del ataque lo interprete como una sílaba, es decir hasta que no sume el valor de una vocal no se garantiza que sea tomada como sílaba... El orden de las reglas, en esa lista previa, determina el orden en que saldrán la silabas, así por ejemplo la primera sílaba que sale es 'bra', porque 'b1' es la primera regla, y la primera opción de 'b1' es 'r1' y la primera opción de 'r1' es 'a3'. Si antepusiera las vocales a las consonantes en la regla 'ataque= vocales|consonantes' , pués entonces la primera sílaba sería la 'a', pués su peso por sí sola ya suma 4. Las últimas sílabas son: 1 ---> u3t6c7h8 7 1 ---> u3t6l8 6 1 ---> u3t6s7 6 1 ---> u3t6t7 6 1 ---> u3t6t7s7 7 1 ---> u3t6t7z8 7 1 ---> u3t6z7 6 1 ---> u3t6z7s7 7 1 ---> u3x6 5 1 ---> u3y6 5 1 ---> u3y6s7 6 1 ---> u3z6 5 1 ---> u3z6s7 6 1 ---> u3z6z8 6
Número de nodos: 101 Total de caminos: 408694 Total de Salidas: 405294
Esta es la salida en la interfaz del programa, en el volcado a fichero se guarda solo las 'silabas' (el nombre completo con sus dígitos). Como se ve a cada sílaba le sucede un dígito, ello obedece a que ese es el nombre para la regla, por debajo hay una pila que verifica si ya consta esa regla, en el stack, si es preciso añadir dos 'z', entonces no sería posible (como en 'zuz', 'jazz'), además si la constante 'r' tiene una regla cuando es la primera letra del ataque (la regla indica que otras letras pueden seguirle), cómo distinguimos entonces la regla si la 'r' aparece en otra posición, un ejemplo de sílaba con 3 'r': 'aho rrarse'?... Podría, al tomar el nombre para entregarlo a la salida, ser filtrado, pero me interesa mantenerlo así, resulta más sencillo de este modo comprobar que se comporta como se espera y si no es así, hacer ajustes, después de todo filtrarlo al término del programa es bastante sencillo y asequible. Nota sin embargo que esto duplica el tamaño del fichero de salida. El número de 'nodos' es la cantidad de reglas, una vez procesadas las directivas, es decir el tamaño del array... La diferencia entre el número de salidas y el de nodos visitados, responde a las consonantes del ataque que por la regla del peso, no logran formar sílaba. Con cada iteración se suma un nodo visitado y con cada sílaba hallada se suma una sílaba de salida. Te dejo enlace a un fichero para descargar, 2 txts, uno tal como sale (más el conjunto de reglas) y otro tras filtrar los dígitos (el primero es para tu análisis si merece (a ti o cualquier otro interesado) el tiempo dedicado en indagar sobre la cuestión y proponer sus propias reglas para crear su variante de reglas para su propio algoritmo: https://workupload.com/file/HbqAsXLsrES (1'94Mb. Aprox. decomprimido son de 5'37Mb. y 3'07Mb.) Y con esto salvo alguna duda al respecto dejo el tema zanjado. Debe quedar claro que un diccionario de 400.000 sílabas es manejable frente a uno de millones, decenas o miles de millones, pués no es más que concatenar x sílabas... o incluso variaciones, donde (por ejemplo) se solicita intercalar 1,2 o 3 dígitos en un punto concreto (nonecesariamente al inicio o final de sílaba), o determinado carácter que se admite como contraseña pero que no es parte del alfabeto A-Z. también hay que tener en cuenta que se dan en minúsculas, una palabra como: 'orden', tiene 120 variaciones (contraseñas distintas) considerando para cada letra si es mayúscula o minúscula (1*2*3*4*5), etc... sobre otras opciones de interés. Ahí en esos detalles es donde uno puede darle juego y esmerarse en programar y no perdiendo tiempo en crear diccionarios gigantes que no aportan nada interesante, de hecho hasta cuesta a uno elegir que conjunto quiere aplicar, por que las reglas son 'el conjunto de palabras que consta en el diccionario', e inntentar filtrarlo por tus propias reglas siendo tan enormes conlleva igualmente mucho tiempo y al caso es preferible perder ese tiempo programando tus propias reglas en tu propio algoritmo. Al final los diccionarios de tamaño medio (pongamos superiores a x Mb. solo tienen utilidad para personas que por no saber programar, tienen que conformarse con algún programa que sea capaz de cargar diferentes diccionarios, si el propio programa no dispone de reglas adecuadas que poder aplicar...
|
|
|
|
|
|
| |
|