Как сгенерировать случайную буквенно-цифровую строку?

Я когда-нибудь использую этот метод:

// It is not importnat what timezone your system is set to.
// Get the UTC offset in seconds:
$offset = date("Z");

// Then subtract if from your original timestamp:
$utc_time = date("Y-m-d H:i:s", strtotime($original_time." -".$offset." Seconds"));

Выполняет все САМЫ времени.

1629
задан 8 revs, 6 users 38% 1 February 2019 в 07:55
поделиться

9 ответов

Алгоритм

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

Реализация

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

import java.security.SecureRandom;
import java.util.Locale;
import java.util.Objects;
import java.util.Random;

public class RandomString {

    /**
     * Generate a random string.
     */
    public String nextString() {
        for (int idx = 0; idx < buf.length; ++idx)
            buf[idx] = symbols[random.nextInt(symbols.length)];
        return new String(buf);
    }

    public static final String upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    public static final String lower = upper.toLowerCase(Locale.ROOT);

    public static final String digits = "0123456789";

    public static final String alphanum = upper + lower + digits;

    private final Random random;

    private final char[] symbols;

    private final char[] buf;

    public RandomString(int length, Random random, String symbols) {
        if (length < 1) throw new IllegalArgumentException();
        if (symbols.length() < 2) throw new IllegalArgumentException();
        this.random = Objects.requireNonNull(random);
        this.symbols = symbols.toCharArray();
        this.buf = new char[length];
    }

    /**
     * Create an alphanumeric string generator.
     */
    public RandomString(int length, Random random) {
        this(length, random, alphanum);
    }

    /**
     * Create an alphanumeric strings from a secure generator.
     */
    public RandomString(int length) {
        this(length, new SecureRandom());
    }

    /**
     * Create session identifiers.
     */
    public RandomString() {
        this(21);
    }

}

примеры Использования

Создают небезопасный генератор для идентификаторов с 8 символами:

RandomString gen = new RandomString(8, ThreadLocalRandom.current());

Создают безопасный генератор для идентификаторов сессии:

RandomString session = new RandomString();

Создают генератор с легкими для чтения кодами для печати. Строки более длинны, чем полные алфавитно-цифровые строки для компенсации использования меньшего количества символов:

String easy = RandomString.digits + "ACEFGHJKLMNPQRUVWXYabcdefhijkprstuvwx";
RandomString tickets = new RandomString(23, new SecureRandom(), easy);

Использование в качестве идентификаторов сессии

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

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

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

Использование в качестве идентификаторов объектов

Не каждое приложение требует безопасности. Случайное присвоение может быть эффективным путем к нескольким объектам для генерации идентификаторов в совместно используемом пространстве без любой координации или разделения. Координация может быть медленной, особенно в кластерной или распределенной среде, и разделение пространства вызывает проблемы, когда объекты заканчиваются с долями, которые являются слишком маленькими или слишком большими.

Идентификаторы, сгенерированные, не принимая меры для создания их непредсказуемыми, должны быть защищены другими средствами, если взломщик мог бы быть в состоянии просмотреть и управлять ими, как это происходит в большинстве веб-приложений. Должна быть отдельная система авторизации, которая защищает объекты, идентификатор которых может быть предположен взломщиком без права доступа.

Уход должен быть также быть взятым для использования идентификаторов, которые достаточно долги для создания коллизий вряд ли, учитывая ожидаемое общее количество идентификаторов. Это упоминается как "парадокс дня рождения". вероятность коллизии, p, приблизительно n <глоток> 2 / (2q <глоток> x ), где n является количеством идентификаторов, на самом деле сгенерированных, , q является количеством отличных символов в алфавите, и , x является длиной идентификаторов. Это должно быть очень небольшим числом, как 2 <глоток> ‑ 50 или меньше.

Работа это показывает, что шанс коллизии среди 500k идентификаторов с 15 символами - приблизительно 2 <глоток> ‑ 52 , который, вероятно, менее вероятен, чем необнаруженные ошибки от космических лучей, и т.д.

Сравнение с UUID

Согласно их спецификации, UUID не разработаны, чтобы быть непредсказуемыми, и не должен использоваться в качестве идентификаторов сессии.

UUID в их стандартном формате занимают много места: 36 символов только для 122 битов энтропии. (Не все биты "случайного" UUID выбраны случайным образом.) Случайным образом выбранная алфавитно-цифровая строка упаковывает больше энтропии во всего 21 символе.

UUID не гибки; у них есть стандартизированная структура и расположение. Это - их главное достоинство, а также их основная слабость. При сотрудничестве с внешней стороной стандартизация, предлагаемая UUID, может быть полезной. Для чисто внутреннего пользования они могут быть неэффективными.

1493
ответ дан 17 revs, 8 users 76% 1 February 2019 в 07:55
поделиться

Здесь это находится в Java:

import static java.lang.Math.round;
import static java.lang.Math.random;
import static java.lang.Math.pow;
import static java.lang.Math.abs;
import static java.lang.Math.min;
import static org.apache.commons.lang.StringUtils.leftPad

public class RandomAlphaNum {
  public static String gen(int length) {
    StringBuffer sb = new StringBuffer();
    for (int i = length; i > 0; i -= 12) {
      int n = min(12, abs(i));
      sb.append(leftPad(Long.toString(round(random() * pow(36, n)), 36), n, '0'));
    }
    return sb.toString();
  }
}

Вот выполненный образец:

scala> RandomAlphaNum.gen(42)
res3: java.lang.String = uja6snx21bswf9t89s00bxssu8g6qlu16ffzqaxxoy
32
ответ дан Apocalisp 1 February 2019 в 07:55
поделиться
static final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
static SecureRandom rnd = new SecureRandom();

String randomString( int len ){
   StringBuilder sb = new StringBuilder( len );
   for( int i = 0; i < len; i++ ) 
      sb.append( AB.charAt( rnd.nextInt(AB.length()) ) );
   return sb.toString();
}
522
ответ дан 5 revs, 5 users 72% 1 February 2019 в 07:55
поделиться

Если Вы рады использовать классы Apache, Вы могли бы использовать org.apache.commons.text.RandomStringGenerator (текст свободного городского населения).

Пример:

RandomStringGenerator randomStringGenerator =
        new RandomStringGenerator.Builder()
                .withinRange('0', 'z')
                .filteredBy(CharacterPredicates.LETTERS, CharacterPredicates.DIGITS)
                .build();
randomStringGenerator.generate(12); // toUpperCase() if you want

, Так как Ленг свободного городского населения 3.6, RandomStringUtils удерживается от использования.

475
ответ дан 10 revs, 9 users 42% 1 February 2019 в 07:55
поделиться

Java предоставляет способ сделать это непосредственно. Если Вы не хотите тире, их легко разделить. Просто используйте uuid.replace("-", "")

import java.util.UUID;

public class randomStringGenerator {
    public static void main(String[] args) {
        System.out.println(generateString());
    }

    public static String generateString() {
        String uuid = UUID.randomUUID().toString();
        return "uuid = " + uuid;
    }
}

Вывод:

uuid = 2d7428a6-b58c-4008-8575-f05549f16316
784
ответ дан 7 revs, 6 users 50% 1 February 2019 в 07:55
поделиться

Я нашел это решение, которое генерирует закодированную строку случайного шестнадцатеричного числа. Обеспеченный модульный тест, кажется, содержит до моего основного варианта использования. Хотя, это немного более сложно, чем некоторые из других предоставленных ответов.

/**
 * Generate a random hex encoded string token of the specified length
 *  
 * @param length
 * @return random hex string
 */
public static synchronized String generateUniqueToken(Integer length){ 
    byte random[] = new byte[length];
    Random randomGenerator = new Random();
    StringBuffer buffer = new StringBuffer();

    randomGenerator.nextBytes(random);

    for (int j = 0; j < random.length; j++) {
        byte b1 = (byte) ((random[j] & 0xf0) >> 4);
        byte b2 = (byte) (random[j] & 0x0f);
        if (b1 < 10)
            buffer.append((char) ('0' + b1));
        else
            buffer.append((char) ('A' + (b1 - 10)));
        if (b2 < 10)
            buffer.append((char) ('0' + b2));
        else
            buffer.append((char) ('A' + (b2 - 10)));
    }
    return (buffer.toString());
}

@Test
public void testGenerateUniqueToken(){
    Set set = new HashSet();
    String token = null;
    int size = 16;

    /* Seems like we should be able to generate 500K tokens 
     * without a duplicate 
     */
    for (int i=0; i<500000; i++){
        token = Utility.generateUniqueToken(size);

        if (token.length() != size * 2){
            fail("Incorrect length");
        } else if (set.contains(token)) {
            fail("Duplicate token generated");
        } else{
            set.add(token);
        }
    }
}
8
ответ дан 4 revs, 4 users 80% 1 February 2019 в 07:55
поделиться

В одной строке:

Long.toHexString(Double.doubleToLongBits(Math.random()));

http://mynotes.wordpress.com/2009/07/23/java-generating-random-string/

104
ответ дан 22 November 2019 в 20:09
поделиться

используя Доллар должен быть простым, так как:

// "0123456789" + "ABCDE...Z"
String validCharacters = $('0', '9').join() + $('A', 'Z').join();

String randomString(int length) {
    return $(validCharacters).shuffle().slice(length).toString();
}

@Test
public void buildFiveRandomStrings() {
    for (int i : $(5)) {
        System.out.println(randomString(12));
    }
}

он выдает нечто подобное:

DKL1SBH9UJWC
JH7P0IT21EA5
5DTI72EO6SFU
HQUMJTEBNF7Y
1HCR6SKYWGT7
42
ответ дан 22 November 2019 в 20:09
поделиться

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

public class AlphaNumericGenerator {

    public static void main(String[] args) {
        java.util.Random r = new java.util.Random();
        int i = 1, n = 0;
        char c;
        String str="";
        for (int t = 0; t < 3; t++) {
            while (true) {
                i = r.nextInt(10);
                if (i > 5 && i < 10) {

                    if (i == 9) {
                        i = 90;
                        n = 90;
                        break;
                    }
                    if (i != 90) {
                        n = i * 10 + r.nextInt(10);
                        while (n < 65) {
                            n = i * 10 + r.nextInt(10);
                        }
                    }

                    break;
                }
            }
            c=(char)n;

            str= String.valueOf(c)+str;
        }
        while(true){
        i = r.nextInt(10000000);
        if(i>999999)
            break;
        }
        str=str+i;
        System.out.println(str);

    }
}
1
ответ дан 22 November 2019 в 20:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: