使用仅包含字母和数字的java.security.SecureRandom生成字符串

时间:2015-05-13 08:13:02

标签: java

我想生成一个字符串(我称之为&#34;盐&#34;但它可能不是正确的术语)仅由字母和数字组成java.security.SecureRandom。< / p>

Random ran = new SecureRandom();
byte [] salt = new byte[32];
ran.nextBytes(salt);
String str = new String(salt,"utf-8");
System.out.println(str);

结果很糟糕,因为它包括像&#34;?#.....&#34;我不想要的。

如何生成类似9c021ac3d11381d9fb2a56b59495f66e的随机字符串?

4 个答案:

答案 0 :(得分:1)

为什么不使用Base64编码转换盐?寻找Apache Commons CodecBase64类。

然后,您可以使用

将字节数组转换为String
Base64.encodeBase64String( salt );

答案 1 :(得分:1)

您可以在BigInteger中转换字节并对其进行基本62(= 10 + 26 + 26)转换。

// Digits listed, so maybe look-alike chars (zero and oh) can be handled.
private static final String digits = "0123...ABC...abc...z";

String humanReadable(byte[] bytes) {

    // Ensure that we have a byte array which is a positive big-endian.
    if (bytes.length != 0 && bytes[0] < 0) {
        byte[] ubytes = new byte[bytes.length + 1];
        System.arraycopy(bytes, 0, ubytes, 1, bytes.length);
        bytes = ubytes;
    }

    BigInteger n = new BigInteger(bytes);
    StringBuilder sb = new StringBuilder(48);
    final BigInteger DIGIT_COUNT = BigInteger.valueOf(digits.length());
    while (n.signum() != 0) {
        int index = n.mod(DIGITS).intValue();
        sb.append(digits.charAt(index));
        n = n.div(DIGITS);
    }
    return sb.toString();
}

答案 2 :(得分:0)

&#34; 9c021ac3d11381d9fb2a56b59495f66e&#34;看起来像盐的十六进制表示。

转换盐可以使用:

String str = bytesToHex(salt);

final protected static char[] hexArray = "0123456789abcdef".toCharArray();
public static String bytesToHex(byte[] bytes) {
    char[] hexChars = new char[bytes.length * 2];
    for ( int j = 0; j < bytes.length; j++ ) {
        int v = bytes[j] & 0xFF;
        hexChars[j * 2] = hexArray[v >>> 4];
        hexChars[j * 2 + 1] = hexArray[v & 0x0F];
    }
    return new String(hexChars);
}

如果速度不重要,您也可以使用:

来自javax.xml.bind.DataTypeConverter

的字符串printHexBinary(byte [])

答案 3 :(得分:0)

下面的课将生成盐。您也可以选择盐的字母和数字。

public class SaltGenerator {
          private static SecureRandom prng;
          private static final Logger LOG = LoggerFactory
                    .getLogger(AuthTokenGenerator.class);
            static {
                try {
                    // Initialize SecureRandom
                    prng = SecureRandom.getInstance("SHA1PRNG");
                } catch (NoSuchAlgorithmException e) {
                    LOG.info("ERROR while intantiating Secure Random:   " + prng);
            }
        }
        /**
         * @return
         */
        public static String getToken() {
            try {
                LOG.info("About to Generate Token in getToken()");
                String token;
                // generate a random number
                String randomNum = Integer.toString(prng.nextInt());
                // get its digest
                MessageDigest sha = MessageDigest.getInstance("SHA-1");
                byte[] result = sha.digest(randomNum.getBytes());
                token = hexEncode(result);
                LOG.info("Token in getToken():   " + token);
                return token;
            } catch (NoSuchAlgorithmException ex) {
                return null;
            }
        }
        /**
         * @param aInput
         * @return
         */
        private static String hexEncode(byte[] aInput) {
            StringBuilder result = new StringBuilder();
            char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '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' };
            for (byte b : aInput) {
                result.append(digits[(b & 0xf0) >> 4]);
                result.append(digits[b & 0x0f]);
            }
            return result.toString();
        }
}