How to generate a secure random alphanumeric string in Java efficiently?

后端 未结 9 1430
半阙折子戏
半阙折子戏 2021-01-01 12:24

How do you generate a secure random (or pseudo-random) alphanumeric string in Java efficiently?

相关标签:
9条回答
  • 2021-01-01 12:43

    My spec for this randomly generated string was to produce a 35 character length encryption key (a-zA-Z2-7 characters only for first 25 chars). After every 5th character a - used, and the last 5 characters were to be an integer between 10_000 and 19_999.

    Here's the code for what I did (in Kotlin).

    companion object {
    
        /**
         * Letters lower & upper case excluding:
         *
         *   - l, o, B, O
         *
         * Numbers excluding:
         *
         *   - 0, 1, 8, 9
         * */
        val acceptedChars: CharArray
            get() = charArrayOf(
                'a', 'b', 'c', 'd', 'e',
                'f', 'g', 'h', 'i', 'j',
                'k', 'm', 'n', 'p', 'q',
                'r', 's', 't', 'u', 'v',
                'w', 'x', 'y', 'z', 'A',
                'C', 'D', 'E', 'F', 'G',
                'H', 'I', 'J', 'K', 'L',
                'M', 'N', 'P', 'Q', 'R',
                'S', 'T', 'U', 'V', 'W',
                'X', 'Y', 'Z', '2', '3',
                '4', '5', '6', '7'
            )
    
        val acceptedInts: CharArray
            get() = charArrayOf(
                '0', '1', '2', '3', '4',
                '5', '6', '7', '8', '9'
            )
    
        fun generate(): EncryptionKey {
            val random = SecureRandom()
            val stringBuilder = StringBuilder()
            for (i in 0 until 35) {
                when (i) {
                    5, 11, 17, 23, 29 -> {
                        stringBuilder.append("-")
                    }
                    30 -> {
                        stringBuilder.append("1")
                    }
                    31, 32, 33, 34 -> {
                        val index = random.nextInt(acceptedInts.size)
                        stringBuilder.append(acceptedInts[index])
                    }
                    else -> {
                        val index = random.nextInt(acceptedChars.size)
                        stringBuilder.append(acceptedChars[index])
                    }
                }
            }
            return EncryptionKey(stringBuilder.toString())
        }
    }
    

    results produced:

    value: 'nK6UI-DWYvu-dbmhD-KPe5X-22dPT-10027', length: '35'
    value: 'NIFvi-aX4GW-3xCYV-YSAVs-tASIK-15301', length: '35'
    value: 'SpNkT-qxHR7-hSMkK-hVxpp-AqLFh-19409', length: '35'
    value: 'bNvi2-svqX7-cfEw5-LNYDn-C2FtW-16197', length: '35'
    value: 'hhjLX-KmRQU-KbHyU-CkNyD-5ASk6-14537', length: '35'
    value: 'Xd2cj-braCm-FaE4E-Jvn2G-2Dv5J-12243', length: '35'
    value: '7beFb-aeSe2-iHXZe-mTUHT-aEbry-17349', length: '35'
    value: 'NExMa-xCAbU-VkpyS-xeEkj-QUayd-16311', length: '35'
    value: '52HWN-EX7wV-csbhj-InhtU-gbV46-18606', length: '35'
    value: 'n3RTZ-whpjQ-ZjW5n-tTyfR-eLDSF-14003', length: '35'
    value: 'aJEks-ccKdU-KGJdh-Rz4ck-tR7Uq-12199', length: '35'
    value: 'nMcUF-ctbcy-FEfq7-VJhRx-pCKej-16369', length: '35'
    
    0 讨论(0)
  • 2021-01-01 12:48

    Here's a slightly modified version of my code from the duplicate question.

    public final class RandomString
    {
    
      /* Assign a string that contains the set of characters you allow. */
      private static final String symbols = "ABCDEFGJKLMNPRSTUVWXYZ0123456789"; 
    
      private final Random random = new SecureRandom();
    
      private final char[] buf;
    
      public RandomString(int length)
      {
        if (length < 1)
          throw new IllegalArgumentException("length < 1: " + length);
        buf = new char[length];
      }
    
      public String nextString()
      {
        for (int idx = 0; idx < buf.length; ++idx) 
          buf[idx] = symbols.charAt(random.nextInt(symbols.length()));
        return new String(buf);
      }
    
    }
    
    0 讨论(0)
  • 2021-01-01 12:49

    Initialize an array containing all the accepted chars (CHARS_ARRAY), then instantiate a SecureRandom instance, and call nextInt(CHARS_ARRAY.length) repeatedly to get a random index in your char array. Append each char to a StringBuilder until you get the expected number of chars.

    0 讨论(0)
  • 2021-01-01 12:51
        String chrs = "0123456789abcdefghijklmnopqrstuvwxyz-_ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        SecureRandom secureRandom = SecureRandom.getInstanceStrong();
        // 9 is the length of the string you want
        String customTag = secureRandom.ints(9, 0, chrs.length()).mapToObj(i -> chrs.charAt(i))
          .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append).toString();
        System.out.println(customTag);
    

    Examples:

    // q3HX6EctP
    // WjRrMjQT4
    // sX-Piq4DB
    
    0 讨论(0)
  • 2021-01-01 12:52
    import java.security.SecureRandom;
    import java.util.Random;
    
    public class PasswordHelper {        
    
        public static String generatePassword (int length) {
    
        //minimum length of 6
        if (length < 4) {
            length = 6;
        }
    
        final char[] allAllowed = "abcdefghijklmnopqrstuvwxyzABCDEFGJKLMNPRSTUVWXYZ0123456789".toCharArray();
    
        //Use cryptographically secure random number generator
        Random random = new SecureRandom();
    
        StringBuilder password = new StringBuilder(); 
    
        for (int i = 0; i < length; i++) {
            password.append(allAllowed[random.nextInt(allAllowed.length)]);
        }
    
        return password.toString();
    
        }
    
    }
    
    0 讨论(0)
  • 2021-01-01 12:54

    Using UUIDs:

    UUID random = UUID.randomUUID();
    System.out.println( random );
    
    0 讨论(0)
提交回复
热议问题