RaphAstronome

mercredi, 7 mai 2008

Vitesse de hachage de fichiers

Non non, je ne mange pas de la purée de fichier tous les matins ! Le hachage des fichiers permet d'avoir une empreinte permettant de vérifier l'intégrité du fichier, par exemple pour vérifier si un téléchargement c'est bien passé. Il est aussi très utilisé pour éviter de mettre les mots de passe en clair quelque part.

Pour les mots de passe le problème de vitesse ne ce pose pas trop car les codes sont très courts (de 8 à 32 octets en général) mais pour les fichiers la vitesse peut être un critère si on gère de gros volumes ou que l'on est sur un serveur mutualisé. Il existe différentes méthodes pour hasher un fichier ici on teste :

  • La somme (sum), dans la pratique vivement déconseillé
  • Le crc (cksum), un peu mieux mais pas top
  • md5 (md5sum)
  • divers algorithmes sha (sha1 sur 160 bits, et les versions 224, 256 et 512 bits), le sha512 est le plus sûr de tous ceux qui sont testés

Les tests ont été faits sur un iso de la distribution Linux Debian qui fait 158,9 Mo. Les temps d'accès au disque ne comptent pas, on suppose qu'il est toujours en mémoire cache. Pour un disque dur moyen (50 Mo/s) il faudrait ajouter a peu près 3,2s.

Les tests mesurent le temps d'exécution réel des commandes Linux indiquées. Pour plus de précision on teste 5 fois et on extrait la valeur médiane :

sum       : 0,563s
cksum     : 0,703s
md5sum    : 0,524s
sha1sum   : 0,892s
sha224sum : 1,577s
sha256sum : 1,572s
sha512sum : 1,085s

vitesse ckecksum

On remarque que c'est le md5sum qui est le plus rapide, encore plus que le "sum" et "cksum". Pour les SHA on évitera les versions 224 et 256 bits, trop lentes et utilisera les versions 160bits ou 512bits.

dimanche, 27 mai 2007

Ruby : open-uri

Voici le problème qui pourrait vous arriver si vous avez comme moi une base de milliers de liens à vérifier. Dans ObjectFinder il y a 2706 : vous comprendrez que les vérifier tous à la main serait pour le moins ennuyeux, il y a même un fort risque de devenir fou avant d'avoir terminé la vérification. Heureusement on peut tout a fait faire un programme qui vérifie les liens pour vous.

Vous vous êtes sûrement demandé comment faire un programme qui télécharge des fichiers, pour ça il existe de différents moyens :

  • Coder un client HTTP avec les sockets : c'est pas hyper dur mais c'est long pour pas grand chose.
  • Utiliser un programme externe comme wget sous Linux mais il faut écrire dans un fichiers puis le lire, pas très propre.
  • Utiliser une librairie : libcurl et autre.

Ruby à en standard une librairie qui permet de charger un fichier distant : 'open-uri'. Bien sur il serait dommage de ne pas l'utiliser.

Son utilisation est simple. Une fonction "open" appelle un bloc où on récupère le flux :

require 'open-uri'

open(adresse) {|f|
	f.each_line {|ligne|
		# ligne est la valeur de la ligne
		# qui est actuellement lue
		puts ligne
	}
}

Une exception est susceptible d'être levée si le fichier n'existe pas ou que le serveur est indisponible.

Donc on oublie pas de le vérifier :

require 'open-uri'

begin
	open(adresse) {|f|
		f.each_line {|ligne|
			# ligne est la valeur de la ligne
			# qui est actuellement lue
			puts ligne
		}
	}
rescue
	puts "Erreur"
end

Attention toutefois ! Quelques précautions doivent êtres prises si vous envoyez beaucoup de requêtes :

  • Le plus important : ralentissez vos requêtes, par exemple une par seconde. Si vous avez beaucoup de liens vous pouvez faire un système qui envoie 1 requête par secondes par serveur (on envoie plusieurs requêtes par seconde mais pas au même serveur).
  • Ne pas charger des fichiers trops gros (éviter de faire les vérifications de téléchargement comme ça).
  • Si vous êtes sur un mutualisé ne lancer pas votre script à partir du serveur mais téléchargez la liste sur votre ordi et exécutez le programme sur votre ordi.
  • Faites un système qui permet de reprendre là où le programme c'est interrompu pour éviter d'avoir à tout refaire en cas de pépin.
  • Soyez patients : ça peut durer un peu de temps mais au moins vous pouvez faire autre chose pendant que le programme tourne (a peu près 1h pour la base d'ObjectFinder).
  • Ne pas recommencer sans arrêt : une fois par mois devrait être largement suffisant.