cs_ym_trainz
Messages postés160Date d'inscriptionvendredi 27 janvier 2006StatutMembreDernière intervention21 avril 2015 18 déc. 2007 à 22:37
Encore moi, Clementio !
En partant donc de ton code, j'ai réussi à encoder 1 Mo en 0,8 secondes !
L'idée c'est de passer par un tableau byte (2 bytes par charactère ascii)
Exemple : si Chaine = "AB"
Tu fais dim Tableau() as byte : redim tableau (len(chaine)*2-1) car de 0 à deux fois la longueur...
Ensuite,
Tableau = chaine ou inversement, et voilà ! Il n'y a plus qu'à faire du Xor octet par octet
Je mets la fonction ci-dessous si ça peut intéresser quelqu'un...
Attention, il faut utiliser la méthode fichier for Binary si on veut exploiter lecture/ ecriture de fichier(genre open path for binary as #n : get #n,,Chaine ou put #...) car les caractères obtenus ne passent plus avec print # ou input #
Le code :
-----------------------------
'Option Explicit
Public Function CrypterDecrypterChaine(StringToCrypt As String, _
CleCryptage As String) As String
'encode ou decode StringToCrypt selon la clé de cryptage CleCryptage
'modif ym_trainz 12/2007
If StringToCrypt = "" Then
'rien à coder
CrypterDecrypterChaine = ""
Exit Function
End If
Dim i As Long, LenToCrypt As Long
Dim Source() As Byte, Destination() As Byte 'le tableau source et destination
Dim ascCrypt() As Byte, LenCle As Long, lPos As Long
'
LenCle = Len(CleCryptage) 'longueur de la clé de cryptage
LenToCrypt = Len(StringToCrypt) * 2 - 1 'ascii sur 2 octets
ReDim ascCrypt(LenCle) 'ascCrypt(0) est inutilisé
ReDim Source(LenToCrypt)
ReDim Destination(LenToCrypt)
Source = StringToCrypt
'
For i = 1 To LenCle
ascCrypt(i) = Asc(Mid(CleCryptage, i)) 'mise en mémoire de la clé en ascii
Next i
'
lPos = 0 'position dans la clé
Dim C As Long
For i = 0 To LenToCrypt
C = i Mod 2048 'toutes les 2048 fois (1 Ko)
'a la place du debug.print, on peut gérer une ProgressBar
If C = 0 Then Debug.Print Int(CDbl(i / CDbl(Len(StringToCrypt))) * 50): DoEvents
lPos = lPos + 1
If lPos > LenCle Then lPos = 1
Destination(i) = Source(i) Xor ascCrypt(lPos) 'codage Xor
Next i
CrypterDecrypterChaine = Destination 'copie directe !!!
End Function
----------------------------------------------
Cordialement,
ym_trainz
cs_ym_trainz
Messages postés160Date d'inscriptionvendredi 27 janvier 2006StatutMembreDernière intervention21 avril 2015 16 déc. 2007 à 23:21
Heu... j'ai encore optimisé : 3 secondes et demi (au lieu des 17 au départ) :
Calculer et mettre en constante Len(Text1.Text) :
Dim LenText As Long
LenText = Len(Text1.Text)
ReDim ascCrypt(LenText) 'ascCrypt(0) est inutilisé
For i = 1 To LenText
ascCrypt(i) = Asc(Mid(Text1.Text, i))
Next i
...
For lCompteur2 = 0 To UBound(bChaine) - 1
If lPos < LenText Then 'et non len(Text1.text)
...
Bon...Merci encore, je vais me servir de ton code.
cs_ym_trainz
Messages postés160Date d'inscriptionvendredi 27 janvier 2006StatutMembreDernière intervention21 avril 2015 16 déc. 2007 à 22:31
et je dirais même plus, on peut encore gagner un chouilla avec
Put #2, , Chr$(bChaine(lCompteur2) Xor ascCrypt(lPos))
Ce qui évite le Cstr(chr()) puisque chr$ convertit en String
cs_ym_trainz
Messages postés160Date d'inscriptionvendredi 27 janvier 2006StatutMembreDernière intervention21 avril 2015 16 déc. 2007 à 22:25
Bravo clementio !
J'ai trouvé une amélioration possible qui fait gagner en vitesse.
J'ai crypté (ou décrypté, c'est idem, nomal ;-) un fichier de 1,39 Mo en 17 secondes.
Avec ma bidouille, je n'ai mis que 10 secondes. Soit 1,6 fois plus vite :
Calculer les codes ascii de la clé une fois pour toute dans un tableau :
Dans Private Sub CPartiMonKiki(), ajouter :
Dim i As Long
Dim ascCrypt() As Byte 'en long, ça va même un poil plus vite
ReDim ascCrypt(Len(Text1.Text)) 'ascCrypt(0) est inutilisé
'on sauvegarde une fois pour toutes dans le tableau
For i = 1 To Len(Text1.Text)
ascCrypt(i) = Asc(Mid(Text1.Text, i))
Next i
...
' remplacer Put #2, , CStr(Chr(bChaine(lCompteur2) Xor Asc(Mid(Text1, lPos, 1)))) par
Put #2, , CStr(Chr(bChaine(lCompteur2) Xor ascCrypt(lPos)))
Bon, je suppose que tu y avais pensé...
En tous cas, bravo ! Simple et efficace.
10/10
Cordialement,
ym_trainz
cs_rocker
Messages postés23Date d'inscriptionmardi 11 octobre 2005StatutMembreDernière intervention21 décembre 2011 18 mars 2007 à 18:15
Très très bien comme source. Manque seulement des commantaires :D
Mayzz
Messages postés2813Date d'inscriptionmardi 15 avril 2003StatutMembreDernière intervention 2 juin 202028 23 oct. 2006 à 04:32
CPartiMonKiki ^^
Très bonne source,
ça fait plaisir de voir qu'il y a enfin des gens qui s'intéressent au traitement des gros fichiers.
Il manque juste des "DoEvents" ou "Sleep" pour éviter de bouffer toute les ressources systèmes, puis une mise en forme du code (module ou classe) et des commentaires !
SkyRocKo
Messages postés174Date d'inscriptionsamedi 10 mai 2003StatutMembreDernière intervention18 février 2006 30 avril 2004 à 21:47
Génial ! 10/10
cs_wbr
Messages postés110Date d'inscriptiondimanche 11 août 2002StatutMembreDernière intervention21 juillet 2006 21 janv. 2003 à 01:23
un seul mot, super! 9/10
clementio
Messages postés432Date d'inscriptionsamedi 18 mai 2002StatutMembreDernière intervention17 février 20141 20 janv. 2003 à 21:16
G pris note de ta remarque et je viens de faire la modif et c vrai que c bcp plus performant, merci.
cs_EBArtSoft
Messages postés4525Date d'inscriptiondimanche 29 septembre 2002StatutModérateurDernière intervention22 avril 20199 20 janv. 2003 à 20:27
C'est bien mais tu devrais plutot charger tout ton fichier dans un tableau genre :
Dim Datas() as Byte
Redim Datas(LOF(1)-1)
Get #1,,Datas
Puis traiter des byte au lieu de charactere tu gagnerais un temp non negligeable sur les gros fichiers et mem sur les petits et rajoute aussi une barre de progression avec un timer du genre si le temp ecouler est superieur 2 deux seconde la barre apparait !!
(A quand le CLM'VB ?)
Voila @+ clementio
cs_LordBob
Messages postés2865Date d'inscriptionsamedi 2 novembre 2002StatutMembreDernière intervention11 mai 20099 20 janv. 2003 à 20:12
18 déc. 2007 à 22:37
En partant donc de ton code, j'ai réussi à encoder 1 Mo en 0,8 secondes !
L'idée c'est de passer par un tableau byte (2 bytes par charactère ascii)
Exemple : si Chaine = "AB"
Tu fais dim Tableau() as byte : redim tableau (len(chaine)*2-1) car de 0 à deux fois la longueur...
Ensuite,
Tableau = chaine ou inversement, et voilà ! Il n'y a plus qu'à faire du Xor octet par octet
Je mets la fonction ci-dessous si ça peut intéresser quelqu'un...
Attention, il faut utiliser la méthode fichier for Binary si on veut exploiter lecture/ ecriture de fichier(genre open path for binary as #n : get #n,,Chaine ou put #...) car les caractères obtenus ne passent plus avec print # ou input #
Le code :
-----------------------------
'Option Explicit
Public Function CrypterDecrypterChaine(StringToCrypt As String, _
CleCryptage As String) As String
'encode ou decode StringToCrypt selon la clé de cryptage CleCryptage
'modif ym_trainz 12/2007
If StringToCrypt = "" Then
'rien à coder
CrypterDecrypterChaine = ""
Exit Function
End If
Dim i As Long, LenToCrypt As Long
Dim Source() As Byte, Destination() As Byte 'le tableau source et destination
Dim ascCrypt() As Byte, LenCle As Long, lPos As Long
'
LenCle = Len(CleCryptage) 'longueur de la clé de cryptage
LenToCrypt = Len(StringToCrypt) * 2 - 1 'ascii sur 2 octets
ReDim ascCrypt(LenCle) 'ascCrypt(0) est inutilisé
ReDim Source(LenToCrypt)
ReDim Destination(LenToCrypt)
Source = StringToCrypt
'
For i = 1 To LenCle
ascCrypt(i) = Asc(Mid(CleCryptage, i)) 'mise en mémoire de la clé en ascii
Next i
'
lPos = 0 'position dans la clé
Dim C As Long
For i = 0 To LenToCrypt
C = i Mod 2048 'toutes les 2048 fois (1 Ko)
'a la place du debug.print, on peut gérer une ProgressBar
If C = 0 Then Debug.Print Int(CDbl(i / CDbl(Len(StringToCrypt))) * 50): DoEvents
lPos = lPos + 1
If lPos > LenCle Then lPos = 1
Destination(i) = Source(i) Xor ascCrypt(lPos) 'codage Xor
Next i
CrypterDecrypterChaine = Destination 'copie directe !!!
End Function
----------------------------------------------
Cordialement,
ym_trainz
16 déc. 2007 à 23:21
Calculer et mettre en constante Len(Text1.Text) :
Dim LenText As Long
LenText = Len(Text1.Text)
ReDim ascCrypt(LenText) 'ascCrypt(0) est inutilisé
For i = 1 To LenText
ascCrypt(i) = Asc(Mid(Text1.Text, i))
Next i
...
For lCompteur2 = 0 To UBound(bChaine) - 1
If lPos < LenText Then 'et non len(Text1.text)
...
Bon...Merci encore, je vais me servir de ton code.
16 déc. 2007 à 22:31
Put #2, , Chr$(bChaine(lCompteur2) Xor ascCrypt(lPos))
Ce qui évite le Cstr(chr()) puisque chr$ convertit en String
16 déc. 2007 à 22:25
J'ai trouvé une amélioration possible qui fait gagner en vitesse.
J'ai crypté (ou décrypté, c'est idem, nomal ;-) un fichier de 1,39 Mo en 17 secondes.
Avec ma bidouille, je n'ai mis que 10 secondes. Soit 1,6 fois plus vite :
Calculer les codes ascii de la clé une fois pour toute dans un tableau :
Dans Private Sub CPartiMonKiki(), ajouter :
Dim i As Long
Dim ascCrypt() As Byte 'en long, ça va même un poil plus vite
ReDim ascCrypt(Len(Text1.Text)) 'ascCrypt(0) est inutilisé
'on sauvegarde une fois pour toutes dans le tableau
For i = 1 To Len(Text1.Text)
ascCrypt(i) = Asc(Mid(Text1.Text, i))
Next i
...
' remplacer Put #2, , CStr(Chr(bChaine(lCompteur2) Xor Asc(Mid(Text1, lPos, 1)))) par
Put #2, , CStr(Chr(bChaine(lCompteur2) Xor ascCrypt(lPos)))
Bon, je suppose que tu y avais pensé...
En tous cas, bravo ! Simple et efficace.
10/10
Cordialement,
ym_trainz
18 mars 2007 à 18:15
23 oct. 2006 à 04:32
Très bonne source,
ça fait plaisir de voir qu'il y a enfin des gens qui s'intéressent au traitement des gros fichiers.
Il manque juste des "DoEvents" ou "Sleep" pour éviter de bouffer toute les ressources systèmes, puis une mise en forme du code (module ou classe) et des commentaires !
30 avril 2004 à 21:47
21 janv. 2003 à 01:23
20 janv. 2003 à 21:16
20 janv. 2003 à 20:27
Dim Datas() as Byte
Redim Datas(LOF(1)-1)
Get #1,,Datas
Puis traiter des byte au lieu de charactere tu gagnerais un temp non negligeable sur les gros fichiers et mem sur les petits et rajoute aussi une barre de progression avec un timer du genre si le temp ecouler est superieur 2 deux seconde la barre apparait !!
(A quand le CLM'VB ?)
Voila @+ clementio
20 janv. 2003 à 20:12