문제

나는 ~을 찾고 있었다 단순한 의사 난수 영숫자 문자열을 생성하는 Java 알고리즘입니다.내 상황에서는 고유할 가능성이 있는 고유 세션/키 식별자로 사용됩니다. 500K+ 세대(내 요구 사항에는 실제로 훨씬 더 정교한 것이 필요하지 않습니다).

이상적으로는 고유성 요구 사항에 따라 길이를 지정할 수 있습니다.예를 들어 생성된 길이 12의 문자열은 다음과 같습니다. "AEYGF7K0DM1X".

도움이 되었습니까?

해결책

연산

무작위 문자열을 생성하려면 문자열이 원하는 길이에 도달할 때까지 허용되는 기호 세트에서 무작위로 그려진 문자를 연결하십시오.

구현

다음은 무작위 식별자를 생성하기 위한 매우 간단하고 유연한 코드입니다. 다음 정보를 읽으십시오. 중요한 애플리케이션 노트용.

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에 포함되거나 직접 다시 입력되는 경우 인코딩 문제가 발생할 수 있습니다.

세션 식별자의 기본 무작위성 소스 또는 엔트로피는 암호화용으로 설계된 난수 생성기에서 나와야 합니다.그러나 이러한 생성기를 초기화하는 것은 때때로 계산 비용이 많이 들거나 느릴 수 있으므로 가능하면 재사용하도록 노력해야 합니다.

객체 식별자로 사용

모든 애플리케이션에 보안이 필요한 것은 아닙니다.무작위 할당은 여러 엔터티가 조정이나 분할 없이 공유 공간에서 식별자를 생성하는 효율적인 방법이 될 수 있습니다.특히 클러스터링되거나 분산된 환경에서는 조정이 느려질 수 있으며, 공간을 분할하면 엔터티가 너무 작거나 큰 공유로 끝날 때 문제가 발생합니다.

예측 불가능하게 만드는 조치를 취하지 않고 생성된 식별자는 대부분의 웹 애플리케이션에서 발생하는 것처럼 공격자가 이를 보고 조작할 수 있는 경우 다른 방법으로 보호되어야 합니다.접근 권한 없이 공격자가 식별자를 추측할 수 있는 객체를 보호하는 별도의 인증 시스템이 있어야 합니다.

또한 예상되는 총 식별자 수를 고려할 때 충돌이 발생하지 않을 정도로 긴 식별자를 사용하는 데에도 주의를 기울여야 합니다.이것을 '생일 역설'이라고 합니다. 충돌 가능성, , 대략 n이다2/(2q엑스), 어디 N 실제로 생성된 식별자의 수입니다. 는 알파벳의 고유 기호 수입니다. 엑스 식별자의 길이입니다.이는 2와 같이 매우 작은 숫자여야 합니다.‑50 이하.

이를 통해 500,000개의 15자 식별자 간의 충돌 가능성이 약 2임을 알 수 있습니다.‑52, 이는 우주선 등으로 인해 감지되지 않은 오류보다 가능성이 낮습니다.

UUID와의 비교

사양에 따르면 UUID는 예측 불가능하도록 설계되지 않았습니다. 해서는 안 된다 세션 식별자로 사용됩니다.

표준 형식의 UUID는 많은 공간을 차지합니다.122비트 엔트로피에는 36자가 필요합니다.("무작위" UUID의 모든 비트가 무작위로 선택되는 것은 아닙니다.) 무작위로 선택된 영숫자 문자열은 단 21자에 더 많은 엔트로피를 포함합니다.

UUID는 유연하지 않습니다.표준화된 구조와 레이아웃을 가지고 있습니다.이것이 그들의 주요 장점이자 주요 약점입니다.외부 당사자와 협력할 때 UUID가 제공하는 표준화가 도움이 될 수 있습니다.순전히 내부용으로는 비효율적일 수 있습니다.

다른 팁

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
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();
}

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

commons-lang 3.6부터 RandomStringUtils 더 이상 사용되지 않습니다.

한 줄에:

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

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

이를 위해 Apache 라이브러리를 사용할 수 있습니다. RandomStringUtils

RandomStringUtils.randomAlphanumeric(20).toUpperCase();

이는 외부 라이브러리 없이도 쉽게 달성할 수 있습니다.

1.암호화 의사 무작위 데이터 생성

먼저 암호화 PRNG가 필요합니다.자바는 SecureRandom 일반적으로 머신에서 가장 좋은 엔트로피 소스를 사용합니다(예: /dev/random) . 여기에서 자세한 내용을 읽어보세요.

SecureRandom rnd = new SecureRandom();
byte[] token = new byte[byteLength];
rnd.nextBytes(token);

메모: SecureRandom Java에서 임의 바이트를 생성하는 가장 느리지만 가장 안전한 방법입니다.그러나 초당 수백만 개의 토큰을 생성해야 하는 경우를 제외하고는 일반적으로 애플리케이션에 실제 영향을 미치지 않으므로 여기에서는 성능을 고려하지 않는 것이 좋습니다.

2.가능한 값의 필수 공간

다음으로 토큰이 "얼마나 고유해야 하는지" 결정해야 합니다.엔트로피를 고려하는 전체적이고 유일한 요점은 시스템이 무차별 대입 공격에 저항할 수 있는지 확인하는 것입니다.가능한 값의 공간은 공격자가 우스꽝스럽지 않은 시간에 무시할 수 있는 값의 비율만 시도할 수 있을 정도로 커야 합니다.1.무작위와 같은 고유 식별자 UUID 122비트의 엔트로피를 가집니다(예:2^122 = 5.3x10^36) - 충돌 가능성은 "*(...)입니다. 중복 가능성이 10억분의 1이 되려면 103조 개의 버전 4 UUID가 생성되어야 합니다.2". 16바이트에 정확히 맞으므로 128비트를 선택하겠습니다. 그리고 다음과 같이 보인다 매우 충분하다 기본적으로 모든 사용 사례에 대해 고유하지만 가장 극단적인 사용 사례에서는 중복에 대해 생각할 필요가 없습니다.다음은 엔트로피의 간단한 분석을 포함한 간단한 엔트로피 비교표입니다. 생일 문제.

comparison of token sizes

간단한 요구 사항의 경우 8바이트 또는 12바이트 길이로 충분할 수 있지만 16바이트를 사용하면 "안전한 측면"에 있습니다.

기본적으로는 그게 전부입니다.마지막으로 인쇄 가능한 텍스트(읽기, String).

삼.바이너리를 텍스트로 인코딩

일반적인 인코딩에는 다음이 포함됩니다.

  • Base64 모든 문자는 6비트를 인코딩하여 33%의 오버헤드를 생성합니다.다행히도 표준 구현이 있습니다. 자바 8+ 그리고 기계적 인조 인간.이전 Java에서는 다음 중 하나를 사용할 수 있습니다. 수많은 타사 라이브러리.토큰을 안전하게 URL로 사용하려면 다음을 사용하세요. URL 안전 RFC4648 버전(일반적으로 대부분의 구현에서 지원됨)패딩을 사용하여 16바이트를 인코딩하는 예: XfJhfv3C0P6ag7y9VQxSbw==

  • Base32 모든 문자는 5비트를 인코딩하여 40%의 오버헤드를 생성합니다.이것은 다음을 사용합니다 A-Z 그리고 2-7 대소 문자를 구분하지 않고 영숫자를 사용하여 합리적으로 공간 효율적으로 만듭니다.없다 JDK의 표준 구현.패딩 없이 16바이트를 인코딩하는 예: WUPIL5DQTZGMF4D3NX5L7LNFOY

  • Base16 (16진수) 모든 문자는 바이트당 2문자가 필요한 4비트를 인코딩합니다(예:16바이트는 길이가 32인 문자열을 생성합니다.따라서 16진수는 다음보다 공간 효율성이 떨어집니다. Base32 하지만 대부분의 경우(url)만 사용하므로 사용하는 것이 안전합니다. 0-9 그리고 A 에게 F.16바이트 인코딩 예: 4fa3dd0f57cb3bf331441ed285b27735. 여기에서 16진수로 변환하는 방법에 대한 SO 토론을 참조하세요.

다음과 같은 추가 인코딩 베이스85 그리고 이국적인 베이스122 더 나은/나쁜 공간 효율성으로 존재합니다.자신만의 인코딩을 만들 수 있지만(기본적으로 이 스레드의 대부분의 답변은 그렇게 함) 구체적인 요구 사항이 없다면 권장하지 않습니다.보다 Wikipedia 기사에서 더 많은 인코딩 체계를 확인하세요.

4.요약 및 예

  • 사용 SecureRandom
  • 최소 16바이트(2^128)의 가능한 값을 사용하세요.
  • 요구 사항에 따라 인코딩합니다(일반적으로 hex 또는 base32 영숫자로 입력해야 하는 경우)

하지 않다

  • ...홈 브루 인코딩을 사용하십시오. 한 번에 문자를 생성하는 이상한 for 루프 대신 사용하는 표준 인코딩을 보면 다른 사람들이 더 잘 유지 관리하고 읽을 수 있습니다.
  • ...UUID 사용: 무작위성을 보장하지 않습니다.6비트의 엔트로피를 낭비하고 있으며 장황한 문자열 표현이 있습니다.

예:16진수 토큰 생성기

public static String generateRandomHexToken(int byteLength) {
    SecureRandom secureRandom = new SecureRandom();
    byte[] token = new byte[byteLength];
    secureRandom.nextBytes(token);
    return new BigInteger(1, token).toString(16); //hex encoding
}

//generateRandomHexToken(16) -> 2189df7475e96aa3982dbeab266497cd

예:Base64 토큰 생성기(URL 안전)

public static String generateRandomBase64Token(int byteLength) {
    SecureRandom secureRandom = new SecureRandom();
    byte[] token = new byte[byteLength];
    secureRandom.nextBytes(token);
    return Base64.getUrlEncoder().withoutPadding().encodeToString(token); //base64 encoding
}

//generateRandomBase64Token(16) -> EEcCCAYuUcQk7IuzdaPzrg

예:자바 CLI 도구

즉시 사용 가능한 cli 도구를 원한다면 dice를 사용할 수 있습니다. https://github.com/patrickfav/dice

사용하여 달러 다음과 같이 간단해야 합니다.

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

다음은 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

놀랍게도 여기에 제안한 사람은 아무도 없습니다.

import java.util.UUID

UUID.randomUUID().toString();

쉬운.

이것의 이점은 UUID가 훌륭하고 길며 충돌이 거의 불가능하다는 것입니다.

Wikipedia에는 ​​이에 대한 좋은 설명이 있습니다.

"...향후 100년 동안 매초 10억 개의 UUID를 생성한 후에야 복제본이 하나만 생성될 확률은 약 50%가 됩니다."

http://en.wikipedia.org/wiki/Universally_unique_identifier#Random_UUID_probability_of_duplicates

처음 4비트는 버전 유형이고 2는 변형이므로 122비트의 무작위를 얻습니다.그래서 당신이 원하다 UUID의 크기를 줄이기 위해 끝부터 잘라낼 수 있습니다.권장되지는 않지만 500,000개의 레코드를 쉽게 생성할 수 있을 만큼 무작위성이 여전히 많습니다.

짧고 쉬운 솔루션이지만 소문자와 숫자만 사용합니다.

Random r = new java.util.Random ();
String s = Long.toString (r.nextLong () & Long.MAX_VALUE, 36);

크기는 36진법으로 약 12자리이며 그런 식으로 더 이상 개선할 수 없습니다.물론 여러 인스턴스를 추가할 수도 있습니다.

Java 8의 대안은 다음과 같습니다.

static final Random random = new Random(); // Or SecureRandom
static final int startChar = (int) '!';
static final int endChar = (int) '~';

static String randomString(final int maxLength) {
  final int length = random.nextInt(maxLength + 1);
  return random.ints(length, startChar, endChar + 1)
        .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
        .toString();
}
public static String generateSessionKey(int length){
String alphabet = 
        new String("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); //9
int n = alphabet.length(); //10

String result = new String(); 
Random r = new Random(); //11

for (int i=0; i<length; i++) //12
    result = result + alphabet.charAt(r.nextInt(n)); //13

return result;
}

UUID를 사용하는 것은 UUID의 일부가 전혀 무작위가 아니기 때문에 안전하지 않습니다.@erickson의 절차는 매우 깔끔하지만 같은 길이의 문자열을 생성하지 않습니다.다음 스니펫이면 충분합니다.

/*
 * The random generator used by this class to create random keys.
 * In a holder class to defer initialization until needed.
 */
private static class RandomHolder {
    static final Random random = new SecureRandom();
    public static String randomKey(int length) {
        return String.format("%"+length+"s", new BigInteger(length*5/*base 32,2^5*/, random)
            .toString(32)).replace('\u0020', '0');
    }
}

선택하는 이유 length*5.길이가 1인 임의의 문자열, 즉 하나의 임의 문자가 있는 간단한 경우를 가정해 보겠습니다.모든 숫자 0-9와 문자 a-z를 포함하는 임의의 문자를 얻으려면 각 문자 중 하나를 얻으려면 0에서 35 사이의 임의의 숫자가 필요합니다. BigInteger 범위에 걸쳐 균일하게 분포된 난수를 생성하는 생성자를 제공합니다. 0 to (2^numBits - 1).불행하게도 35는 2^numBits - 1로 받을 수 있는 숫자가 아닙니다.따라서 두 가지 옵션이 있습니다.같이 가거나 2^5-1=31 또는 2^6-1=63.우리가 선택한다면 2^6 우리는 "불필요한" / "더 긴" 숫자를 많이 얻게 될 것입니다.그러므로 2^5 4자(w-z)가 손실되더라도 더 나은 옵션입니다.이제 특정 길이의 문자열을 생성하려면 간단히 2^(length*numBits)-1 숫자.마지막 문제는 특정 길이의 문자열을 원하는 경우 무작위로 작은 숫자가 생성될 수 있으므로 길이가 충족되지 않으므로 문자열 앞에 0을 붙여 필요한 길이만큼 채워야 한다는 것입니다.

import java.util.Random;

public class passGen{
    //Verison 1.0
    private static final String dCase = "abcdefghijklmnopqrstuvwxyz";
    private static final String uCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static final String sChar = "!@#$%^&*";
    private static final String intChar = "0123456789";
    private static Random r = new Random();
    private static String pass = "";

    public static void main (String[] args) {
        System.out.println ("Generating pass...");
        while (pass.length () != 16){
            int rPick = r.nextInt(4);
            if (rPick == 0){
                int spot = r.nextInt(25);
                pass += dCase.charAt(spot);
            } else if (rPick == 1) {
                int spot = r.nextInt (25);
                pass += uCase.charAt(spot);
            } else if (rPick == 2) {
                int spot = r.nextInt (7);
                pass += sChar.charAt(spot);
            } else if (rPick == 3){
                int spot = r.nextInt (9);
                pass += intChar.charAt (spot);
            }
        }
        System.out.println ("Generated Pass: " + pass);
    }
}

따라서 이것이 수행하는 작업은 문자열에 비밀번호를 추가하는 것입니다.응 잘된다 확인해봐...매우 간단합니다.내가 썼어

임의의 16진수로 인코딩된 문자열을 생성하는 이 솔루션을 찾았습니다.제공된 단위 테스트는 나의 주요 사용 사례에 적합한 것 같습니다.그러나 제공된 다른 답변 중 일부보다 약간 더 복잡합니다.

/**
 * 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);
        }
    }
}
import java.util.Date;
import java.util.Random;

public class RandomGenerator {

  private static Random random = new Random((new Date()).getTime());

    public static String generateRandomString(int length) {
      char[] values = {'a','b','c','d','e','f','g','h','i','j',
               'k','l','m','n','o','p','q','r','s','t',
               'u','v','w','x','y','z','0','1','2','3',
               '4','5','6','7','8','9'};

      String out = "";

      for (int i=0;i<length;i++) {
          int idx=random.nextInt(values.length);
          out += values[idx];
      }
      return out;
    }
}
import java.util.*;
import javax.swing.*;
public class alphanumeric{
    public static void main(String args[]){
        String nval,lenval;
        int n,len;

        nval=JOptionPane.showInputDialog("Enter number of codes you require : ");
        n=Integer.parseInt(nval);

        lenval=JOptionPane.showInputDialog("Enter code length you require : ");
        len=Integer.parseInt(lenval);

        find(n,len);

    }
    public static void find(int n,int length) {
        String str1="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        StringBuilder sb=new StringBuilder(length);
        Random r = new Random();

        System.out.println("\n\t Unique codes are \n\n");
        for(int i=0;i<n;i++){
            for(int j=0;j<length;j++){
                sb.append(str1.charAt(r.nextInt(str1.length())));
            }
            System.out.println("  "+sb.toString());
            sb.delete(0,length);
        }
    }
}
  1. 요구 사항에 따라 문자열 문자를 변경하십시오.

  2. 문자열은 변경할 수 없습니다.여기 StringBuilder.append 문자열 연결보다 효율적입니다.


public static String getRandomString(int length) {
       final String characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJLMNOPQRSTUVWXYZ1234567890!@#$%^&*()_+";
       StringBuilder result = new StringBuilder();
       while(length > 0) {
           Random rand = new Random();
           result.append(characters.charAt(rand.nextInt(characters.length())));
           length--;
       }
       return result.toString();
    }

"간단한" 솔루션에 관한 답변이 마음에 들지 않습니다.

나는 간단한;), 순수 Java, 하나의 라이너를 선택합니다(엔트로피는 임의의 문자열 길이와 주어진 문자 세트를 기반으로 함).

public String randomString(int length, String characterSet) {
    return IntStream.range(0, length).map(i -> new SecureRandom().nextInt(characterSet.length())).mapToObj(randomInt -> characterSet.substring(randomInt, randomInt + 1)).collect(Collectors.joining());
}

@Test
public void buildFiveRandomStrings() {
    for (int q = 0; q < 5; q++) {
        System.out.println(randomString(10, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"));//charachterSet can basically be anything
    }
}

또는 (좀 더 읽기 쉬운 옛날 방식)

public String randomString(int length, String characterSet) {
    StringBuilder sb = new StringBuilder(); //consider using StringBuffer if needed
    for (int i = 0; i < length; i++) {
        int randomInt = new SecureRandom().nextInt(characterSet.length());
        sb.append(characterSet.substring(randomInt, randomInt + 1));
    }
    return sb.toString();
}

@Test
public void buildFiveRandomStrings() {
    for (int q = 0; q < 5; q++) {
        System.out.println(randomString(10, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")); //charachterSet can basically be anything
    }
}

그러나 반면에 꽤 좋은 엔트로피를 갖는 UUID를 사용할 수도 있습니다(https://en.wikipedia.org/wiki/Universally_unique_identifier#Collisions):

UUID.randomUUID().toString().replace("-", "")

도움이 되길 바랍니다.

"간단함"을 언급하셨지만 다른 사람이 보다 엄격한 보안 요구 사항을 충족하는 것을 찾고 있는 경우를 대비해 다음을 살펴보는 것이 좋습니다. jpwgen.jpwgen은 다음을 모델로 한 것입니다. pwgen Unix에서는 매우 구성 가능합니다.

다음은 Scala 솔루션입니다.

(for (i <- 0 until rnd.nextInt(64)) yield { 
  ('0' + rnd.nextInt(64)).asInstanceOf[Char] 
}) mkString("")

getLeastSignificantBits() 메시지와 함께 UUID 클래스를 사용하여 64비트의 무작위 데이터를 가져온 다음 이를 기수 36 숫자로 변환할 수 있습니다(예:0-9,A-Z로 구성된 문자열):

Long.toString(Math.abs( UUID.randomUUID().getLeastSignificantBits(), 36));

그러면 최대 13자 길이의 문자열이 생성됩니다.Math.abs()를 사용하여 빼기 기호가 몰래 들어가지 않는지 확인합니다.

비밀번호 필수에 숫자, 알파벳 특수 문자가 포함된 경우 다음 코드를 사용할 수 있습니다.

private static final String NUMBERS = "0123456789";
private static final String UPPER_ALPHABETS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final String LOWER_ALPHABETS = "abcdefghijklmnopqrstuvwxyz";
private static final String SPECIALCHARACTERS = "@#$%&*";
private static final int MINLENGTHOFPASSWORD = 8;

public static String getRandomPassword() {
    StringBuilder password = new StringBuilder();
    int j = 0;
    for (int i = 0; i < MINLENGTHOFPASSWORD; i++) {
        password.append(getRandomPasswordCharacters(j));
        j++;
        if (j == 3) {
            j = 0;
        }
    }
    return password.toString();
}

private static String getRandomPasswordCharacters(int pos) {
    Random randomNum = new Random();
    StringBuilder randomChar = new StringBuilder();
    switch (pos) {
        case 0:
            randomChar.append(NUMBERS.charAt(randomNum.nextInt(NUMBERS.length() - 1)));
            break;
        case 1:
            randomChar.append(UPPER_ALPHABETS.charAt(randomNum.nextInt(UPPER_ALPHABETS.length() - 1)));
            break;
        case 2:
            randomChar.append(SPECIALCHARACTERS.charAt(randomNum.nextInt(SPECIALCHARACTERS.length() - 1)));
            break;
        case 3:
            randomChar.append(LOWER_ALPHABETS.charAt(randomNum.nextInt(LOWER_ALPHABETS.length() - 1)));
            break;
    }
    return randomChar.toString();

}

다음은 한 줄 코드입니다. AbacusUtil

String.valueOf(CharStream.random('0', 'z').filter(c -> N.isLetterOrDigit(c)).limit(12).toArray())

무작위라고 해서 고유해야 한다는 의미는 아닙니다.다음을 사용하여 고유한 문자열을 얻으려면:

N.uuid() // e.g.: "e812e749-cf4c-4959-8ee1-57829a69a80f". length is 36.
N.guid() // e.g.: "0678ce04e18945559ba82ddeccaabfcd". length is 32 without '-'

Apache 라이브러리를 사용하면 한 줄로 완료할 수 있습니다.

import org.apache.commons.lang.RandomStringUtils;
RandomStringUtils.randomAlphanumeric(64);

여기 문서가 있습니다 http://commons.apache.org/lang/api-2.3/org/apache/commons/lang/RandomStringUtils.html

public static String randomSeriesForThreeCharacter() {
    Random r = new Random();
    String value="";
    char random_Char ;
    for(int i=0; i<10;i++)
    { 
        random_Char = (char) (48 + r.nextInt(74));
        value=value+random_char;
    }
    return value;
}

나는 이것이 여기서 가장 작은 솔루션이거나 거의 가장 작은 솔루션 중 하나라고 생각합니다.

 public String generateRandomString(int length) {
    String randomString = "";

    final char[] chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890".toCharArray();
    final SecureRandom random = new SecureRandom();
    for (int i = 0; i < length; i++) {
        randomString = randomString + chars[random.nextInt(chars.length)];
    }

    return randomString;
}

코드가 잘 작동합니다.이 방법을 사용한다면 10자 이상을 사용하는 것이 좋습니다.충돌은 5자/30362 반복에서 발생합니다.9초가 걸렸습니다.

public static String getRandomString(int length) 
{
   String randomStr = UUID.randomUUID().toString();
   while(randomStr.length() < length) {
       randomStr += UUID.randomUUID().toString();
   }
   return randomStr.substring(0, length);
}

아마도 이것이 도움이 될 것입니다

package password.generater;

import java.util.Random;

/**
 *
 * @author dell
 */
public class PasswordGenerater {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        int length= 11;
        System.out.println(generatePswd(length));

        // TODO code application logic here
    }
    static char[] generatePswd(int len){
        System.out.println("Your Password ");
        String charsCaps="ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
        String Chars="abcdefghijklmnopqrstuvwxyz";
        String nums="0123456789";
        String symbols="!@#$%^&*()_+-=.,/';:?><~*/-+";
        String passSymbols=charsCaps + Chars + nums +symbols;
        Random rnd=new Random();
        char[] password=new char[len];

        for(int i=0; i<len;i++){
            password[i]=passSymbols.charAt(rnd.nextInt(passSymbols.length()));
        }
      return password;

    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top