Foro de elhacker.net

Programación => Programación Visual Basic => Mensaje iniciado por: lessionone en 13 Abril 2012, 10:57 am



Título: concatenacion de string y se queda pillado
Publicado por: lessionone en 13 Abril 2012, 10:57 am
Hola buenas, tengo un trozo de codigo fuente que se me queda pillado en el visual studio, al parecer el procesador se pone a trabajar a tope y nada.(es un core 2 duo p8600 y 4 gb de memoria)
Código:
 Private Function encriptararchivo(ByVal archivooriginal As String) As String
        Dim c As String = ""
        Dim z As String = ""
        Dim y As Integer=0
        For b = 1 To Len(archivooriginal)
            c = Mid(archivooriginal, b, 1)
            y = Asc(c)
            z = z & y & "tallin"
        Next
        Return z
me he inclinado por escribir en el subforo de criptografia ya que vosotros entendeis perfectamente algoritmos rc4, xor y estos funcionan a la perfeccion a la hora de ejecutarlos en un ordenador sin necesitad de un gran procesador ni memoria.
He de decir que la variable archivooriginal es un archivo leido en binario y por eso lo paso a ascci, y que el numero de veces que debe de pasar por el bucle es de 697373.
Si yo le pongo 100000 lo realiza pero le cuesta aunque sin duda lo que mas le cuesta es ir concatenando en la variable z ya que si quito esta concatenacion pues hace el bucle y todas las instrucciones muy rapidas.
¿En rc4 no concatena el texto del archivo que le pasa? si es asi como que con rc4 no se queda pillado y con esto que es una tonteria si?
¿como podria hacerlo sin usar concatenacion?
Si creeis que esto pertenece mas a programacion decirmelo y lo muevo.
Gracias.


Título: Re: concatenacion de string y se queda pillado
Publicado por: Yoghurt en 11 Julio 2012, 10:49 am
Amigo creo que aun no conoces las Arrays, cuando concatenas las variables en Visual Basic pasa justamente eso, el computador se vuelve lento y más si le pasas archivos pesados. Intenta Aprendiendo que son los Arrays y como funcionan, luego sustituye la concatenación con un array.

(te sugiero deshacerte de "tallin" no sirve!!)

primero hay que inicializar la array para reservarle memoria, en este caso será la longitud del archivo.
Código:
Dim z[] As String 'crea un array de String
ReDim z[0 to (len(archivooriginal))

luego sustituye la concatenación por:
Código:
z[b] = y & "tallin"

y para pasarlo de Array a String usa:
Código:
archivofinal = join(z, "")

O pasalo directamente a un archivo en el disco duro:
Código:
Open "archivo final" for Binary Access Write Lock Write As #2
put #2, 0, z
Close #2

Y no olvides de liberar la memoria de z:
Código:
ReDim z[0]

Notaste que la concatenacion al igual que el array pesa 6 veces más por ese estupido TALLIN!!??? Espero hayas aprendido que la memoria es inversamente proporcional a la velocidad (en la informatica).


Título: Re: concatenacion de string y se queda pillado
Publicado por: Yoghurt en 11 Julio 2012, 11:13 am
En RC4 y otros algoritmos de codificación lo que hacen para que al contrario de ti no se queden sin memoria, es no ocupar el puto "tallin"! (perdón pero me saca dequicio)  :D jajajajaja...

Bueno, lo que hacen ellos es dividir el texto a cifrar en pedazos más pequeños para de esta forma ocupar menos espacio en memoria y ser más eficientes puesto que consigen más velocidad haciendo eso.

Con tu algoritmo pasa lo siguiente: Codificas un archivo en el disco de 3MB por ejemplo, pero para codificarlo lo tubiste que poner en una variable (archivooriginal) que pesa lo mismo que el archivo en disco 3MB, luego lo pasas ya cifrado a la variable z que ocupará 3MB más, pero como le pones "tallin" a cada caracter pesa 6 veces más por lo que z pesa en realidad 21MB, entonces tienes:

archivooriginal = 3MB
z = 21MB
Resultado = 24MB ocupados por tu programa en RAM

Increible verdad. Bueno te recomiendo leer solo pedazos directamente del archivo en disco utilizando una variable String como buffer que lea solo X caracteres (X es un numero dependiendo de tus necesidades Ej: 24) y los codifique y luego los ponga directamente en un archivo en el disco... Asi solo ocupas 24bits + (24bits * 6bits) = 168bits!  Claro, como el Disco Duro es mas lento que la RAM se demora un poco más pero es solo un poco más.


Título: Re: concatenacion de string y se queda pillado
Publicado por: 79137913 en 11 Julio 2012, 15:52 pm
HOLA!!!

No le hagas caso a AbrahamAraon, el desentiende este lenguaje parece , te esta explicando poniendo corchetes en vez de parentesis, eso denota una total ignorancia de la sintaxis del lenguaje.

Siguiendo:

El problema esta en estas lineas:
Código
  1. Dim c As String = ""
  2.        Dim z As String = ""
  3.        Dim y As Integer=0
  4.  
Por que al declarar esas variables no se les puede dar un valor. (aunque todas de inicializan con el valor que igualas ahi)
Tenes que poner asi para que funcione:
Código
  1. Dim c As String
  2.        Dim z As String
  3.        Dim y As Integer
  4.        c = ""
  5.        z = ""
  6.        y = 0
  7.  
Como veras ahi separo la declaracion de la asignacion de valor de la variable.

Luego tambien estas mal con esta linea:
Código
  1. Return z
En VB6 no se usa Return, para que la funcion devuelva esa variable que indicas ahi deberias reemplazar esa linea por:
Código
  1. encriptararchivo = z

Por ultimo nunca cerras la funcion.
Deberias agregar un End Function al final.

El codigo te quedaria asi:
Código
  1. Private Function encriptararchivo(ByVal archivooriginal As String) As String
  2.        Dim c As String
  3.        Dim z As String
  4.        Dim y As Integer
  5.        c = ""
  6.        z = ""
  7.        y = 0
  8.        For b = 1 To Len(archivooriginal)
  9.            c = Mid(archivooriginal, b, 1)
  10.            y = Asc(c)
  11.            z = z & y & "tallin"
  12.        Next
  13.        encriptararchivo = z
  14. End Function
  15.  

P.D: @lessionone solo arregle tus problemas con la sintaxis no cambie el funcionamiento de tu funcion.
P.D2: @AbrahamAraon Si respondes por favor responde bien o aunque sea en el lenguaje del subforo correspondiente, No hagas doble post, modifica el ultimo post y agrega lo que tengas que agregar, arriba ya te dije que no se usan corchetes en vb6, se usan parentesis.

GRACIAS POR LEER!!!


Título: Re: concatenacion de string y se queda pillado
Publicado por: seba123neo en 11 Julio 2012, 23:20 pm
por el codigo que pone lessionone, parece que esta programando en visual basic .net

igual es verdad, la concatenacion de strings en visual basic es super lenta en bucles de miles, hay un post que hice con una clase que usa CopyMemory que puede llegar a concatenar millones de strings en muy poco tiempo. el equivalente de esto en .NET es la clase StringBuilder.


Título: Re: concatenacion de string y se queda pillado
Publicado por: Yoghurt en 12 Julio 2012, 06:39 am
Lo siento por el descuido, aprate de los corchetes (esq se me cruzan los lenguajes) no noté otros errores en el código de lessionone, espero le ayude de todas formas ;)


Título: Re: concatenacion de string y se queda pillado
Publicado por: BlackZeroX en 12 Julio 2012, 22:55 pm
Código:
[quote author=lessionone link=topic=359048.msg1737017#msg1737017 date=1334307451]
...
[code]
 Private Function encriptararchivo(ByVal archivooriginal As String) As String
        Dim c As String = ""
        Dim z As String = ""
        Dim y As Integer=0
        For b = 1 To Len(archivooriginal)
            c = Mid(archivooriginal, b, 1)
            y = Asc(c)
            z = z & y & "tallin"
        Next
        Return z
...
[/quote]

para ese algoritmo sencillo se puede calcular facilmente el buffer que utilizara.

bufferSize = (SizeOfFile * lenWord) + (SizeOfFile / NumberOfChars)
es decir:
bufferSize = (len(archivooriginal) * len("tallin")) + (len(archivooriginal) / 1)

Aun que a mi sinceramente no me agrada usar los strings para trabajar con archivos...

Código
  1.  
  2. ...
  3.        z = space((len(archivooriginal) * len("tallin")) + (len(archivooriginal) / 1))
  4.  
  5.        For b = 1 To Len(archivooriginal)
  6.            mid(z, c, 1) = mid(archivooriginal, i, 1) // no recuerdo si en .Net puedo seguir usando el mid() del lado izuierdo del igual...
  7.            mid(z, c + 1, len("tallin")) = "tallin"
  8.            c = c + 1 + len("tallin")
  9.        Next
  10.  
  11.        Return z
  12. ...
  13.  

Me tendré que instalar otra vez el vb6...

Dulces Lunas!¡.[/code]


Título: Re: concatenacion de string y se queda pillado
Publicado por: BlackZeroX en 13 Julio 2012, 00:46 am
Asi es como yo lo haria... los algoritmos funcionan tan rapido que procesa un archivo de 17 megabytes en unos segundos... con un archivo de salida de casi 190 megabytes...

Código
  1.  
  2. Option Explicit
  3.  
  4. Private Declare Sub RtlMoveMemory Lib "kernel32" (ByVal pDst As Long, ByVal pSrc As Long, ByVal ByteLen As Long)
  5.  
  6. Private Sub Form_Load()
  7. Dim ff          As Long
  8. Dim mapFile()   As Byte
  9.  
  10.    ff = FreeFile
  11.    Open "c:\hola.txt" For Binary As ff
  12.        If Not EOF(ff) Then
  13.            ReDim mapFile(0 To LOF(ff) - 1)
  14.            Seek ff, 1  '  nos posicionamos al inicio del archivo
  15.            Get ff, , mapFile
  16. '                Debug.Print StrConv(mapFile, vbUnicode)
  17.            Seek ff, 1  '  nos posicionamos al inicio del archivo
  18.                mapFile = fisuras(mapFile, StrConv("BlackZeroX", vbFromUnicode))
  19. '                Debug.Print StrConv(mapFile, vbUnicode)
  20.            Put ff, , mapFile
  21.        End If
  22.    Close ff
  23. End Sub
  24.  
  25.  
  26. Private Function fisuras(ByRef arr() As Byte, ByRef words() As Byte) As Byte()
  27. Dim size    As Long
  28. Dim newSize As Long
  29. Dim sizeW   As Long
  30. Dim ret()   As Byte
  31. Dim i       As Long, j  As Long ', k  As Long
  32.  
  33.    size = (UBound(arr) + 1)
  34.    sizeW = (UBound(words) + 1)
  35.    newSize = (size * sizeW + size / 1)
  36.  
  37.    ReDim ret(0 To (newSize - 1))
  38.  
  39.    For i = 0 To (size - 1)
  40.        ret(j) = arr(i): j = (j + 1)
  41.        RtlMoveMemory VarPtr(ret(j)), VarPtr(words(0)), sizeW   '   For k = 0 To (sizeW - 1): ret(j + k) = words(k): Next
  42.        j = (j + sizeW)
  43.    Next
  44.  
  45.    fisuras = ret
  46.  
  47. End Function
  48.  
  49.  

o tambien asi:

Código
  1.  
  2. Option Explicit
  3.  
  4. Private Sub Form_Load()
  5. Dim ff          As Long
  6. Dim mapFile()   As Byte
  7.  
  8.    ff = FreeFile
  9.    Open "c:\hola.txt" For Binary As ff
  10.        If Not EOF(ff) Then
  11.            ReDim mapFile(0 To LOF(ff) - 1)
  12.            Seek ff, 1  '  nos posicionamos al inicio del archivo
  13.            Get ff, , mapFile
  14. '                Debug.Print StrConv(mapFile, vbUnicode)
  15.            Seek ff, 1  '  nos posicionamos al inicio del archivo
  16.                mapFile = fisuras(mapFile)
  17. '                Debug.Print StrConv(mapFile, vbUnicode)
  18.            Put ff, , mapFile
  19.        End If
  20.    Close ff
  21. End Sub
  22.  
  23.  
  24. Private Function fisuras(ByRef arr() As Byte, Optional ByRef text As String = "BlackZeroX") As Byte()
  25. Dim size    As Long
  26. Dim newSize As Long
  27. Dim lenText As Long
  28. Dim ret()   As Byte
  29. Dim i       As Long, j  As Long, k  As Long
  30.  
  31.    size = (UBound(arr) + 1)
  32.    lenText = Len(text)
  33.    newSize = (size * lenText + size / 1)
  34.  
  35.    ReDim ret(0 To (newSize - 1))
  36.  
  37.    For i = 0 To (size - 1)
  38.        ret(j) = arr(i)
  39.        For k = 1 To lenText
  40.            ret(j + k) = Asc(Mid(text, k, 1))
  41.        Next
  42.        j = (j + 1 + lenText)
  43.    Next
  44.  
  45.    fisuras= ret
  46.  
  47. End Function
  48.  
  49.  

Dulces Lunas!¡.


Título: Re: concatenacion de string y se queda pillado
Publicado por: BlackZeroX en 13 Julio 2012, 02:18 am

Y no olvides de liberar la memoria de z:
Código:
ReDim z[0]


para liberar se usa erase...

erase z

Aun que si las variables estan declaradas en un proceso estas son automáticas y la llamada a erase se obvia... caso omiso cuando pides memoria...

OJO Mientras mas grande sea el buffer te quedaras sin memoria... tambien ten en consideracion que si lees trozos desde tu HD como dice @AbrahamAraon solo es en cuestión a que sea un archivo PESADO (DEFINICIÓN mas de 100 megas e inclusive hasta 4 Gigas o mas...), mientras no sean archivos super pesados, es mejor CARGAR TODO el archivo en memoria y crear memoria que actué como buffer de esta manera se evita estar leyendo el archivo constantemente y evitamos la latencia que esta representa a su vez aumentamos la velocidad de procesamiento...

* No uses String para leer archivos si es que los vas a procesar,
* Usa array de bytes par procesar archivos un caracter de una string es equivalente a 2 bytes... y en si aun que tu veas 10 caracteres pesaras que pesa en memoria 10 bytes pero la realidad es que pesa 20 bytes...

Dulces Lunas!¡.


Título: Re: concatenacion de string y se queda pillado
Publicado por: Yoghurt en 13 Julio 2012, 08:19 am
Me ha pasado casos en los que me da error al usar ERASE por lo que uso ReDim para las array, a nadie más le ha dado error?. Y... si que se esfuerzan en el código ustedes cosa que yo no hago en el foro, pero tengan fé de que lo haré ;)  Solo que no se formen una idea equivocada pues siempre busco la manera más eficiente para mi codigo. y BlackZeroX (Astaroth) difiero de ti en lo del Disco Duro, tal vez tengas una Computadora Genial, pero no todos tienes grandes recursos, no me digas que no recuerdas al marivilloso Pentium III, yo aun tengo un computador de 700MHz con 64Mb de RAM (antes tenia 128 pero las rams se queman)... Y no le veo la debilidad de usar un buffer de lectura, divide y vencerás!


Título: Re: concatenacion de string y se queda pillado
Publicado por: BlackZeroX en 13 Julio 2012, 08:41 am
.
ammm sabes que latencia ofrece una memoria primaria a una secundaria?, es demasiada la diferencia... jamas dije que es malo leer de trozos en trozos, es bueno en algunos casos, pero para saber cuanto buffer debemos establecer hay que hacer algunos cálculos entre el tiempo de procesamiento y la carga de los datos... un ejemplo de esto es por ejemplo Nero, Alcohol, etc... crear un buffer de por lo menos 256 megas o arriba de 100 megas no recuerdo cual es el mínimo, para no interrumpir la escritura de un datos en un disco, mientras en segundo plano se cargan los datos...

 *En el tema de la PC, tengo dos PC es "Intel Pentium 4 + 256 megas con un HDD de 80 Gigas a 7200 RPM" y la otra es una "AMD Phenom II X4 965 Black Edition + 16 Gigas de RAM DDR3 con un HDD de 1 Tera a 7200 RPM", y la verdad NO noto diferencia entre aplicaciones creadas en VB6 (por el tema de los hilos), en pocas palabras no veo la forma en que vb6 tenga un gran impacto en la velocidad entre ambas PC'S, lo que si te puedo asegurar es que para leer trozos a trozos los datos y a su vez procesarlos si el proceso es muy rapido con es este el caso es mejor cargar el archivo prácticamente con buffers de 50 a 100 megas o lo que se requiera (considerando la pequeña latencia perjudicial de lectura), en caso contrario si el procesamiento es LEEENTO y complejo seria bueno cargar entre 1 a 10 megas o lo que se requiera.

Dulces Lunas!¡.


Título: Re: concatenacion de string y se queda pillado
Publicado por: Yoghurt en 13 Julio 2012, 20:24 pm
"AMD Phenom II X4 965 Black Edition + 16 Gigas de RAM DDR3 con un HDD de 1 Tera a 7200 RPM"

Con eso dominaras el mundo.