Генерация неповторяющегося списка буквенно-цифровых кодов - PullRequest
1 голос
/ 09 декабря 2010

Я пытаюсь создать список неповторяющихся буквенно-цифровых кодов. Они будут сгенерированы партиями и в таких объемах, что невозможно будет явно посмотреть на то, что было сгенерировано ранее - то есть уникальность должна быть каким-то образом гарантирована без обращения к предыдущим кодам вне текущего пакета.

Коды должны иметь длину 8 символов с ограничением на то, что определенные символы не могут появляться в коде (например, l и L), поскольку пользователь будет вводить их повторно позже.

Я, вероятно, реализую это в Java, но я был бы признателен за любые алгоритмы или приемы, которые кто-либо может придумать для решения этой проблемы ...

С уважением,

Ответы [ 7 ]

4 голосов
/ 09 декабря 2010

Просто возьмите System.currentTimeMillis и закодируйте его буквенно-цифровым способом, сопоставляя каждую цифру букве. Следите за последним выпущенным (для защиты повторов нескольких поколений за одну и ту же миллисекунду) и обрабатывайте соответственно.

3 голосов
/ 09 декабря 2010

Вы можете просто закодировать атомный счетчик, такой как

AtomicInteger counter = new AtomicInteger();

public String generateId() {
   return Integer.toHexString(counter.getAndIncrement());
}

Это даст вам 4 миллиарда уникальных идентификаторов.

Если вам нужно более 4 миллиардов, вы можете использовать AtomicLong и использовать свою собственную кодировку для этого числа в зависимости от того, какие символы вы хотите разрешить.

2 голосов
/ 09 декабря 2010

Указанная проблема имеет очевидное решение: генерировать коды последовательно, начиная с нуля. Думайте о каждом коде как о числе в base-34 (цифры 0-9 и A-Z, за исключением I и L). Если это не то, что вам нужно, вы можете уточнить вопрос (например, хотите ли вы случайности?)

edit : Это, конечно, требует, чтобы вы помнили последний сгенерированный вами код и передавали этот фрагмент информации между партиями.

0 голосов
/ 25 апреля 2019

Проверьте эту логику. Вы можете исключить любой алфавит или число в цикле. На ваш вопрос «L» вы можете исключить следующее

        if(brokenCode[i] == 'K') brokenCode[i] = 'L'; 
        brokenCode[i] = (char)(((int)brokenCode[i]) + 1);

Пример кода

class Rextester
{  
    public static void main(String args[])
    {
        String currCode = "00000000";
        for(int i=0; i<2000; i++)
        {
            System.out.println(currCode);
            currCode = getNextCode(currCode);
        }
    }

    private static String getNextCode(String currCode)
    {
        char [] brokenCode;
        brokenCode = currCode.toCharArray();
        for(int i=brokenCode.length-1; i>= 0; i--)
        {
            if(brokenCode[i] == '9')
            {
                brokenCode[i] = 'A';
                break;
            }
            if(brokenCode[i] == 'Z'){
                brokenCode[i] = '0';
                continue;
            }
            brokenCode[i] = (char)(((int)brokenCode[i]) + 1);
            break;
        }
        currCode = new String(brokenCode);
        return currCode;
    }

}
0 голосов
/ 09 декабря 2010

Можете ли вы выполнить итерацию вперед следующим образом?

000000a1 000000a2 000000a3 ... 000000ay 000000az 000000b0

Тогда просто запомните последнее число, и все будущие числа будут больше последнего

Вы можете найти это полезным

long l = 20492;
String s = "wogjz";
s = Long.toString(l, 26+10-2).replace('I','Y').replace('L','Z') // convert long number to string (with letters)
l = Long.parseLong(s.replace('Y','I').replace('Z','L'), 26+10-2) + 1) // Convert string to number

Число 26 + 10-2 - это количество букв плюс количество цифр минус количество запрещенных букв (I и L).Преобразование I / Y и Z / L заключается в использовании последних букв алфавита в сотрудничестве с библиотекой Java.

Вы хотите убедиться, что пользователь не вводит I или L самостоятельно, потому что мой кодиначе работать не будет.

Вы захотите добавлять начальные нули в строку, пока она не достигнет 8 символов

Также моя программа не знает разницы между большими и маленькими буквами.Если вам это нужно, тогда приложение должно быть более сложным, потому что нам нужен массив вместо одного длинного числа.

0 голосов
/ 09 декабря 2010

Жаль, что вы ограничены 8 символами. В противном случае вы могли бы использовать класс MD5 для генерации уникальных кодов.

В любом случае, если вы хотите, чтобы ваши коды были уникальными, вы можете закодировать дату генерации в некоторых символах кода, чтобы она не конфликтовала с предыдущими кодами.

Например, ваш код будет иметь форму YMDXXXXX, где:

  • Y - это год с 2010 года (начинайте с 0 и начинайте использовать буквы, когда у вас заканчиваются цифры в 2020 году)
  • М - месяц (те же критерии)
  • D - день (не будет больше 31, поэтому символов 0-9A-Z должно быть достаточно)
  • X - коды, сгенерированные для вашей текущей партии.
0 голосов
/ 09 декабря 2010

8 вложенных циклов решают вашу проблему тривиально.Более того, если вы хотите, вы можете использовать Random, чтобы сгенерировать следующий токен и сохранить все токены в Set.Каждый раз, когда вы получаете новый токен, проверяйте, есть ли он уже в наборе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...