Не извлекайте существующие коды, просто сгенерируйте потенциальный новый код и посмотрите, есть ли какие-либо конфликтующие в базе данных:
SELECT code FROM table WHERE abs(code-?) regexp '^[1-9]?0*$';
(где заполнитель - это недавно сгенерированный код).
Ах, я пропустил генерацию большого количества кодов сразу.Сделайте это так (полностью не проверено):
my @codes = existing_codes();
my $frontwards_index = {};
my $backwards_index = {};
for my $code (@codes) {
index_code($code, $frontwards_index);
index_code(reverse($code), $backwards_index);
}
my @new_codes = map generate_code($frontwards_index, $backwards_index), 1..10000;
sub index_code {
my ($code, $index) = @_;
push @{ $index{ substr($code, 0, length($code)/2) } }, $code;
return;
}
sub check_index {
my ($code, $index) = @_;
my $found = grep { ($_ ^ $code) =~ y/\0//c <= 1 } @{ $index{ substr($code, 0, length($code)/2 } };
return $found;
}
sub generate_code {
my ($frontwards_index, $backwards_index) = @_;
my $new_code;
do {
$new_code = sprintf("%07d", rand(10000000));
} while check_index($new_code, $frontwards_index)
|| check_index(reverse($new_code), $backwards_index);
index_code($new_code, $frontwards_index);
index_code(reverse($new_code), $backwards_index);
return $new_code;
}