簡體   English   中英

如何在Perl中創建唯一標識符?

[英]How can I create unique identifiers in Perl?

我正在創建一個面向文件的數據庫,其中包含各種用戶執行的一些測試結果。 為此,我需要為數據庫中的每個條目生成唯一的id。 ID必須滿足以下要求:

  • Ids應該相當小(最多6個字符)
  • 對於每個測試用例和用戶組合,每次應生成相同的id

我嘗試的是一個簡單的BKDR哈希函數,其種子值為31,並使用了ord()函數,如下所示:

@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" ;

這有時會導致各種組合的相同結果,即未觀察到唯一性。 他們是否有其他方法可以實現這一目標? 改變種子價值有助於實現獨特性。

每個用戶有超過256個用戶和/或超過65536個測試用例嗎? 如果沒有,你可以只從0 ... 255索引用戶並測試0到65535的情況,並將其編碼為十六進制數字字符串,這樣六個字符就可以了。

如果你有更多的用戶或測試用例,我會再次索引用戶和測試用例,然后將它們組合成一個32位整數,實際上只需要4個字節,並且可以實現,但對人類來說稍微有點難度。

無論如何,我假設您獲得了用戶名和測試用例信息。 只需保留兩個綁定的哈希值: %users%cases將map用戶和測試用例映射到索引號。

您的部分問題可能是您正在使用浮點數學,而BKDR幾乎肯定需要整數數學。 您可以通過說明修復該錯誤

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" ;

另一個可能有用的調整是使用除第一個和最后一個之外的字符。 如果第一個和最后一個字符趨於相同,則它們不會為哈希添加唯一性。

您可能還想使用更好的哈希函數,如MD5(在Digest :: MD5中可用),並將結果修剪為所需的大小。 但是,您使用哈希的事實意味着您有可能發生沖突。

如果您沒有很多用戶/測試用例,這樣的簡單解決方案就足夠了。 您必須添加限制(並且可能在存儲時包裝整數)。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM