Je recherche une fonction de contrôle de chaîne Perl avec les propriétés suivantes:
$ string code>) li>
- sortie: integer non signé (
$ hash code>), pour lequel 0 <= $ hachage <= 2 ^ 32-1 code> est contenant (0 à 4294967295, correspondant à la taille de la taille de un 4 octet mysql non signé int) li>
ul> pseudo-code: p> xxx pré> idéalement la fonction de contrôle doit être rapide à exécuter et générer des valeurs uniformément uniformément dans l'espace cible ( 0 code> .. 2 ^ 32-1 code>) pour éviter les collisions. Dans cette application, les collisions aléatoires sont totalement non mortelles, mais évidemment, je veux les éviter dans la mesure du possible. P> Compte tenu de ces exigences, quelle est la meilleure façon de résoudre ce problème? < / b> p> p>
3 Réponses :
Je ne sais pas à quel point il est rapide, mais vous pouvez essayer String :: CRC a>. p>
Toute fonction de hachage suffira - tout simplement tronquer à 4 octets et convertir en un nombre. Les bonnes fonctions de hachage ont une distribution aléatoire et cette distribution sera constante, peu importe où vous tronquez la chaîne.
Je suggère Digest :: MD5 Parce que c'est la mise en œuvre de hachage la plus rapide fournie avec Perl en standard. String :: CRC, en tant que mention de PIM, est également implémenté dans C et devrait être plus rapide. P>
Voici comment calculer le hachage et le convertir en entier: P>
use Digest::MD5 qw(md5); my $str = substr( md5("String-to-hash"), 0, 4 ); print unpack('L', $str); # Convert to 4-byte integer (long)
B :: Hash est également livré avec Core Perl, utilise la fonction Hash Core interne, est plus rapide que MD5 et renvoie un entier hexifié 32 bits. Mais pas aussi sécurisé que MD5.
de perdoc -f Déballez CODE>:
For example, the following computes the same number as the
System V sum program:
$checksum = do {
local $/; # slurp!
unpack("%32W*",<>) % 65535;
};
Ces sommes de 32 bits de tous les bits sont une très mauvaise valeur de hachage pour les distributions aléatoires. Toute fonction de hachage est meilleure, même les plus simples.
Bien sûr, mais c'est le même problème que le programme System V Somme code> est. Voir le paragraphe. Ou affirmez-vous que
somme code> est sans doute cassé? Dans ce cas, il ne s'agit pas de Perl.
Somme code> est à peu près aussi rapide que vous obtiendrez, comme indiqué ci-dessus, ce n'est pas terriblement robuste. Vous pouvez l'améliorer légèrement en utilisant la taille, par exemple.
$ _ = <>; Déballez ("% 32w *", $ _)% 65535. Longueur ($ _) code>. Tout ce qui doit être plus robuste devrait utiliser
Digest :: MD5 code> ou
Digest :: SHA CODE>, etc., etc.
Vous voulez éviter les collisions avec toutes les cordes possibles, mais seulement un digestion possible de 4 milliards de personnes possibles? Pourquoi utiliser un entier important? Que diriez-vous d'utiliser quelque chose comme MD5, même si vous devez stocker le digest comme une chaîne?
"Vous voulez éviter les collisions avec toutes les chaînes possibles" - non, comme indiqué dans la question que je veux simplement "vouloir les éviter dans la mesure du possible".
"Pourquoi utiliser un entier important?" - Comme indiqué dans la question, la somme de contrôle sera stockée dans "un 4 octet mysql non signé INT".