2015-05-13 2 views
0

Я хочу сгенерировать строку (я называю это «солью», но это, вероятно, не правильный термин), состоящий только из букв и цифр с помощью java.security.SecureRandom ,Создание строки с java.security.SecureRandom, которая включает только буквы и цифры

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

В результате получается плохо, потому что он включает в себя такие вещи, как «? # .....», который я не хочу.

Как я могу создать случайную строку, которая похожа на 9c021ac3d11381d9fb2a56b59495f66e?

+0

возможно дубликат [Как генерировать случайные буквенно-цифровую строку?] (Http://stackoverflow.com/questions/41107/how-to-generate-a-random-alpha-numeric-string) – ceekay

+0

Автор хочет создать случайную строку, состоящую из букв и цифр. Это не соль, поэтому я исключил этот термин в основном (оставив пояснительную записку). Это заставляет вопрос отвечать, но он, вероятно, слишком широк, потому что OP не прилагает никаких усилий в своем коде, чтобы ограничить случайную строку буквами и цифрами, поэтому неудивительно, что результат не ограничивается буквами и цифрами. –

ответ

0

"9c021ac3d11381d9fb2a56b59495f66e" выглядит как шестнадцатеричное представление вашей соли.

Для преобразования соли вы можете использовать:

String str = bytesToHex(salt); 

final protected static char[] hexArray = "abcdef".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); 
} 

Если скорость не важна, вы также можете использовать:

Строка printHexBinary (байт []) из javax.xml.bind.DataTypeConverter

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

Почему бы не использовать кодировку Base64 для преобразования соли? Ищите Apache Commons Codec, Base64 класс.

Вы можете затем преобразовать массив байтов в строку с помощью

Base64.encodeBase64String(salt); 
+0

Да, Base64 = 10 цифр + 26 маленьких букв + 26 заглавных букв + 2 специальных символа. Так почти подходит. Эти два специальных символа также могут быть безопасными для URL. Java 8 консолидировала кодировку BASE64 в конечном классе Base64. –

+0

@JoopEggen Да, помимо специальных символов (+/и =) ... Может быть, не совсем то, что хочет OP. Вероятно, лучше, если OP использует SO duplicate-link ... –

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(); 
} 
Смежные вопросы