Question

Je suis en train de créer une base de données orientée fichiers de certains résultats des tests effectués par les différents utilisateurs. Pour cela, je dois générer id unique pour chaque entrée dans la base de données. Les ids doivent satisfaire aux exigences suivantes:

  • Ids devrait être assez petit (6 caractères au maximum)
  • Pour tous les cas de test et la combinaison de l'utilisateur à chaque fois même identifiant doit être généré

Ce que j'ai essayé était une simple fonction de hachage BKDR avec une valeur de 31 graines et utilisé la fonction ord () comme suit:

@chars = split(//,$hash_var);

$hash = 0;
$seed = 31;

foreach $char ( @chars ) {
   if( $char !~ m/\d/ ) {
       $hash = ( $seed * $hash ) + ord( $char );
   }  
   else {
       $hash = ( $seed * $hash ) + $char ;
   }
}

$hash = ( $hash & 0x7FFFFFFF ) % 1000;
$hash = "$chars[0]$chars[$#chars]$hash" ;

Cela conduit parfois à des résultats même pour diverses combinaisons i.e. unicité n'est pas observée. Leur toute autre façon d'y parvenir? Est-ce que l'évolution de l'aide de la valeur de la graine accomplir unique.

Était-ce utile?

La solution

Une partie de votre problème peut être que vous utilisez les mathématiques à virgule flottante et BKDR manque presque certainement mathématiques entier. Vous pouvez corriger ce bug en disant

my @chars = split(//,$hash_var);

my $hash = 0;
my $seed = 31;

for my $char ( @chars ) {
   use integer;
   if( $char !~ m/\d/ ) {
       $hash = ( $seed * $hash ) + ord( $char );
   }  
   else {
       $hash = ( $seed * $hash ) + $char ;
   }
}

$hash = ( $hash & 0x7FFFFFFF ) % 1000;
$hash = "$chars[0]$chars[$#chars]$hash" ;

Un autre tweak qui pourrait aider est d'utiliser des caractères autres que le premier et le dernier. Si les premiers et derniers caractères ont tendance à être les mêmes, ils ajoutent pas unique au hachage.

Vous pouvez également utiliser une meilleure fonction de hachage comme MD5 (disponible dans Digest :: MD5) et couper le résultat à la taille désirée. Cependant, le fait que vous utilisez un hachage à tous les moyens que vous courez le risque d'avoir une collision.

Autres conseils

Avez-vous plus de 256 utilisateurs et / ou plus de 65536 cas de test par utilisateur? Sinon, vous pouvez seulement les utilisateurs d'index de 0 .. 255 et cas de test de 0 .. 65535 et encodez comme une chaîne de chiffres hexadécimaux donc six caractères serait bien.

Si vous avez plusieurs utilisateurs ou des cas de test que, je index à nouveau les utilisateurs et les cas de test, puis les combiner en un entier de 32 bits qui fait prendre seulement 4 octets et être trivial à mettre en œuvre, mais un peu plus difficile sur les humains .

Dans tous les cas, je suppose que vous donne le nom d'utilisateur et de cas de test. Il suffit de garder deux hash à égalité:. Et %users pour mapper les utilisateurs %cases et des cas de test à leur index

Si vous ne disposez pas d'un grand nombre d'utilisateurs / TestCases une solution simple comme cela pourrait être suffisant. Il faudrait ajouter la limite (et probablement emballer l'entier lors de son stockage).

vinko@parrot:~# more hash.pl
use strict;
use warnings;

my %hash;
my $count = 0;

sub getUniqueId {

        my $_user = shift;
        my $_test = shift;
        my $val;

        my $key = $_user."|".$_test;
        if (defined $hash{$key}) {
                $val = $hash{$key};
        } else {
                $hash{$key} = $count;
                $val = $count;
                $count = $count + 1;
        }
        return $val;
}

my @users = qw{ user1 user2 user3 user4 user5 user3 user5 };
my @testcases = qw{ test1 test2 test3 test1 test1 };

for my $user (@users) {
        for my $test (@testcases) {
                print "$user $test: ".getUniqueId($user,$test)."\n";
        }
}
vinko@parrot:~# perl hash.pl
user1 test1: 0
user1 test2: 1
user1 test3: 2
user1 test1: 0
user1 test1: 0
user2 test1: 3
user2 test2: 4
user2 test3: 5
user2 test1: 3
user2 test1: 3
user3 test1: 6
user3 test2: 7
user3 test3: 8
user3 test1: 6
user3 test1: 6
user4 test1: 9
user4 test2: 10
user4 test3: 11
user4 test1: 9
user4 test1: 9
user5 test1: 12
user5 test2: 13
user5 test3: 14
user5 test1: 12
user5 test1: 12
user3 test1: 6
user3 test2: 7
user3 test3: 8
user3 test1: 6
user3 test1: 6
user5 test1: 12
user5 test2: 13
user5 test3: 14
user5 test1: 12
user5 test1: 12
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top