Can we generate multiple random strings as per regex /^[0-9A-F]$/
I have written the below code, is there any better way to generate it, please do not use any lib, use only java API
public static void printRandomStrings(int numOfStrings){
Random random = new Random();
char[] chars = {'A','B','C','D','E','F'}; // 6 characters
for(int i=0;i<numOfStrings;i++){
String randomString = "";
for(int j=0;j<4;j++){
int choice = random.nextInt(2); // 0 -1
if(choice == 1){
randomString= randomString+generateRandomInt(random);
}else{
randomString= randomString+generateRandomChar(random,chars);
}
}
System.out.println(randomString);
}
}
public static int generateRandomInt(Random random){
return random.nextInt(10);
}
public static char generateRandomChar(Random random,char[] chars){
int charIdx = random.nextInt(6);
return chars[charIdx];
}
Related
Hi I am trying to generate a 5 digit random number which is alpha numeric in nature. I am doing both with without using Streams.
CODE
public class AlphaRandom {
private static final String ALPHA_NUMERIC_STRING = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
static final Random random = new Random();
public static void main(String args[]) {
int length = 5;
String seq = randomAlphaNumeric(length);
System.out.println("Random Number Normal : " +seq);
IntStream.range(0,1).forEach(i->System.out.println("Random Number Streams : " +generateRandomString(random, length)));
}
// Using Streams
private static String generateRandomString(Random random, int length){
return random.ints(48,122)
.filter(i-> (i<57 || i>65) && (i <90 || i>97))
.mapToObj(i -> (char) i)
.limit(length)
.collect(StringBuilder::new, StringBuilder::append, StringBuilder::append)
.toString();
}
// Normal
public static String randomAlphaNumeric(int count) {
StringBuilder builder = new StringBuilder();
while (count-- != 0) {
int character = (int)(Math.random()*ALPHA_NUMERIC_STRING.length());
builder.append(ALPHA_NUMERIC_STRING.charAt(character));
}
return builder.toString();
}
}
Sample Outputs :
Random Number Normal : VYAXC
Random Number Streams : LdBN6
Random Number Normal : 2ANTT
Random Number Streams : hfegc
Random Number Normal : JWK4Y
Random Number Streams : 8mQXK
But I am unable to generate the sequence always starting with a UpperCase only.
Can someone help me out.
I will use RandomStringUtils from the apache library to do this. The reason to do this is less code and I believe better readability of the code.
This is my code which can do the required thing
import org.apache.commons.lang3.RandomStringUtils;
public class GenerateRandomString {
public static void main(String[] args) {
int keyLength = 5; // Number of character allowed as per requirement
String randomAlphanumeric = RandomStringUtils.randomAlphanumeric(keyLength);
System.out.println("randomAlphanumeric generated is " + randomAlphanumeric);
String upperCaseRandom = randomAlphanumeric.substring(0, 1).toUpperCase() + randomAlphanumeric.substring(1);
System.out.println("upperCaseRandom generated is " + upperCaseRandom);
}
}
It would generate the following output:
randomAlphanumeric generated is m8OiR
upperCaseRandom generated is M8OiR
I am making the first character to uppercase as required by question using the substring method.
The easiest way is that before to return your string (once you have generated it), you take the first letter in order to apply toUpperCase and on the remaining chars, apply toLowerCase. Also, if in the future you will need to generate longer strings, you can use the same method without changing anything.
Summering what we'll do is:
public static String manipulate (String rand){
String c = rand.substring(0,1); // where rand is the random alphanumeric generated by your methods, we pick the first char
c = c.toUpperCase(); //we make it upperCase
String split = rand.substring(1); //we get the remaining of the string starting from position 1
split = split.toLowerCase(); //let's apply lowercase on the remaining
String result = c+split; //join again
return result;
}
Full Code:
package test;
import java.util.Random;
import java.util.stream.IntStream;
public class AlphaRandom {
private static final String ALPHA_NUMERIC_STRING = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
static final Random random = new Random();
public static void main(String args[]) {
int length = 5;
String seq = randomAlphaNumeric(length);
System.out.println("Random Number Normal : " +seq);
IntStream.range(0,1).forEach(i->System.out.println("Random Number Streams : " +generateRandomString(random, length)));
}
public static String manipulate (String rand){
String c = rand.substring(0,1); // where rand is the random alphanumeric generated by your methods, we pick the first char
c = c.toUpperCase(); //we make it upperCase
String split = rand.substring(1); //we get the remaining of the string starting from position 1
split = split.toLowerCase(); //let's apply lowercase on the remaining
String result = c+split; //join the again
return result;
}
// Using Streams
private static String generateRandomString(Random random, int length){
String rand = random.ints(48,122)
.filter(i-> (i<57 || i>65) && (i <90 || i>97))
.mapToObj(i -> (char) i)
.limit(length)
.collect(StringBuilder::new, StringBuilder::append, StringBuilder::append)
.toString();
return manipulate(rand);
}
// Normal
public static String randomAlphaNumeric(int count) {
StringBuilder builder = new StringBuilder();
while (count-- != 0) {
int character = (int)(Math.random()*ALPHA_NUMERIC_STRING.length());
builder.append(ALPHA_NUMERIC_STRING.charAt(character));
}
return manipulate(builder.toString());
}
}
Output:
Random Number Normal : Mwwsz
Random Number Streams : Q1fqk
This question already has answers here:
How to generate a random alpha-numeric string
(46 answers)
Closed 6 years ago.
I'm trying to generate a string between capital A-Z in java using Secure Random. Currently I'm able to generate an alphanumeric string with special characters but I want a string with only upper case alphabets.
public String createRandomCode(int codeLength, String id){
char[] chars = id.toCharArray();
StringBuilder sb = new StringBuilder();
Random random = new SecureRandom();
for (int i = 0; i < codeLength; i++) {
char c = chars[random.nextInt(chars.length)];
sb.append(c);
}
String output = sb.toString();
System.out.println(output);
return output ;
}
The input parameters are length of the output string & id whhich is alphanumeric string.Can't understand what modifications to make to the above code to generate only upper case alphabet string. Please help..
Your method randomly selects characters out of the id argument. If you want those to only be uppercase letters, then pass a string with those characters:
String randomCode = createRandomCode(length, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
EDIT If you want to avoid duplicates, you can't just select characters at random. You'll want to shuffle them and pick out the first n characters:
public String createRandomCode(int codeLength, String id) {
List<Character> temp = id.chars()
.mapToObj(i -> (char)i)
.collect(Collectors.toList());
Collections.shuffle(temp, new SecureRandom());
return temp.stream()
.map(Object::toString)
.limit(codeLength)
.collect(Collectors.joining());
}
EDIT 2 Just for fun, here's another way to implement the original random code generator (allowing duplicates):
public static String createRandomCode(int codeLength, String id) {
return new SecureRandom()
.ints(codeLength, 0, id.length())
.mapToObj(id::charAt)
.map(Object::toString)
.collect(Collectors.joining());
}
Here is generator that I wrote and use:
public class RandomGenerator {
private static final String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static String generateRandom(int length) {
Random random = new SecureRandom();
if (length <= 0) {
throw new IllegalArgumentException("String length must be a positive integer");
}
StringBuilder sb = new StringBuilder(length);
for (int i = 0; i < length; i++) {
sb.append(characters.charAt(random.nextInt(characters.length())));
}
return sb.toString();
}
}
in numChars string you can put any characters you want to be included. int length parameter is the length of generated random string.
Here is an example method that uses the int range for characters A to Z (also this method avoids duplicate characters in the String) :
public String createRandomCode(final int codeLength) {
int min = 65;// A
int max = 90;// Z
StringBuilder sb = new StringBuilder();
Random random = new SecureRandom();
for (int i = 0; i < codeLength; i++) {
Character c;
do {
c = (char) (random.nextInt((max - min) + 1) + min);
} while (sb.indexOf(c.toString()) > -1);
sb.append(c);
}
String output = sb.toString();
System.out.println(output);
return output;
}
The range part comes from this topic : Generating random integers in a specific range
I'm writing a short program which be able to generate 5 digits code mixed with 0-9, a-z, A-Z.
This is my code:
import java.util.*;
public class FiveDigitsRandom
{
public static void main(String[] args)
{
new FiveDigitsRandom().use();
}
public void use()
{
char choice;
while((choice=readChar()) != 'x')
{
switch(choice)
{
case'n':
generateAll();
break;
}
}
}
public char readChar()
{
System.out.print("Please choose n/x: ");
Scanner scanner = new Scanner(System.in);
return scanner.nextLine().charAt(0);
}
public void generateAll()
{
String[]code = new String[5];
for(int i=0; i<code.length; i++)
{
int random = generate0_2();
switch(random)
{
case 0:
code[i] = generate0_9();
break;
case 1:
code[i] = generate_a_z();
break;
case 2:
code[i] = generate_A_Z();
break;
}
}
for(int j=0; j<code.length; j++)
{
System.out.print(code[j]);
}
System.out.println(" ");
}
public int generate0_2()
{
return (int)Math.random()*3;
}
public String generate0_9()
{
int a = (int)(Math.random() * 10);
String AA = Integer.toString(a);
return AA;
}
public String generate_a_z()
{
char a = (char)((int)'a'+ Math.random() * ((int)'z' - (int)'a' + 1));
String AA = Character.toString(a);
return AA;
}
public String generate_A_Z()
{
char a = (char)((int)'A'+ Math.random() * ((int)'Z' - (int)'A' + 1));
String AA = Character.toString(a);
return AA;
}
}
It suppose to generate a random code as 0AzhG, Hg78N. But now I can only have 5 digits code with random number 0-9. Please tell me where is wrong in my code??
Thank you!
Your generate0_2 method is wrong.
public int generate0_2()
{
return (int)Math.random()*3;
}
When you cast it to int, it works like ((int)Math.random)*3 which means, it provides 0 every time.
change it to
public int generate0_2()
{
return (int)(Math.random()*3);
}
A problem you have is that your won't have an even distribution. i.e. individual digits are more likely than individual letters. One way to have an even distribution is you have an even function.
public static char randomChar() {
// random.nextInt(62) would be faster.
int n = (int) (Math.random() * 62);
if (n < 10) return (char) ('0' + n);
n -= 10;
if (n < 26) return (char) ('A' + n);
n -= 26;
return (char) ('a' + n);
}
public static String randomString(int length) {
char[] chars = new char[length];
for (int i = 0; i < length; i++)
char[i] = randomChar();
return new String(chars);
}
Maybe it's easely to use RandomStringUtils
import org.apache.commons.lang3.RandomStringUtils;
class Main {
public static void main(String[] args) {
// Prints only A-Z, a-z, 0-9
System.out.println(RandomStringUtils.randomAlphabetic(5));
// Prints only A-Z, a-z
System.out.println(RandomStringUtils.randomAlphanumeric(5));
}
}
I'm interested in generating a (secure) random String with the following properties:
Atleast 1 upper case letter
Atleast 1 lower case letter
Atleast 1 digit from 0-9
Atleast one special char from chars $&#?<>~!%#
The length of string should be from 12-13 digits/chars long.
I know there is a class in Apache commons that can help generate random Strings however there is no option to include special chars.
I'm also aware of some other similar questions on SO however none of them address exactly these requirements.
I've tried the following so far:
import java.security.SecureRandom;
public final class SessionIdentifierGenerator {
private SecureRandom random = new SecureRandom();
public String nextSessionId() {
return
new BigInteger(130, random).toString(32);
}
}
But it does not contain char set from each of the 4 points.
I also tried:
static final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static Random rnd = new Random();
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();
}
I know I can modify the String AB to include special chars but there's no way to guarantee string will contain Atleast 1 upper, 1 lower, 1 digit and 1 special char.
I'm using Java.
The easiest way in your case is to generate the random password containing any of allowed symbols, then test whether the criteria met:
private static final String symbols =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789$&#?<>~!%#";
public static String genPassword(Random r) {
while(true) {
char[] password = new char[r.nextBoolean()?12:13];
boolean hasUpper = false, hasLower = false, hasDigit = false, hasSpecial = false;
for(int i=0; i<password.length; i++) {
char ch = symbols.charAt(r.nextInt(symbols.length()));
if(Character.isUpperCase(ch))
hasUpper = true;
else if(Character.isLowerCase(ch))
hasLower = true;
else if(Character.isDigit(ch))
hasDigit = true;
else
hasSpecial = true;
password[i] = ch;
}
if(hasUpper && hasLower && hasDigit && hasSpecial) {
return new String(password);
}
}
}
According to my tests, number of required iterations rarely exceeds 5 and in more than half tests the first generated password meets the criteria. Though don't force your users to memoize such passwords! Here's how they look like:
c3h$oyuKcZZl
Si4e8F4sWjy#i
V$9WwW7zJ8ba
~9htwMwcFc!s
wBm94~AH%z%MU
p4TE36S&Y>J14
R9Bsqq#23eYk
PTfcvR5u?piZQ
CE8ot>a74PmZP
4zAco~P6Xuf3E
aiv?VDN4j9pE
Set up an array/list/whatever of characters. Pick a random lowercase letter and put it into your array. Pick a random uppercase letter and put it into your array. Pick a random digit and put it into your array. Pick a random special character and put it into your array. You have four characters in your array which partly meets your requirements.
Now pick as many more characters as you need at random from the string: "A-Za-z0-9$&#?<>~!%#" Add each selected character to your character array.
Now shuffle your character array to mess up the order of the first four characters.
Convert the shuffled array to a string.
The following works well for me. Note, that you could pass in a specific Random implementation if you didn't want to use RandomUtils.
public class RandomUtil {
public static final String ALPHABETIC_UPPERCASE_SYMBOLS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static final String ALPHABETIC_LOWERCASE_SYMBOLS = "abcdefghijklmnopqrstuvwxyz";
public static final String NUMERIC_SYMBOLS = "0123456789";
public static final String SPECIAL_SYMBOLS = "$&#?<>~!%#";
public static final String ALPHANUMERIC_AND_SPECIAL_SYMBOLS =
ALPHABETIC_UPPERCASE_SYMBOLS +
ALPHABETIC_LOWERCASE_SYMBOLS +
NUMERIC_SYMBOLS +
SPECIAL_SYMBOLS;
public static String generateRandomAlphanumericAndSpecialCharactersKey(int length) {
List<Character> chars = new ArrayList<>(length);
boolean hasUpper = false;
boolean hasLower = false;
boolean hasNumber = false;
boolean hasSpecial = false;
for (int i = 0; i < length; i++) {
// Make sure we have at least one upper, lower, number and special character.
// Then, fill randomly from set containing all characters.
if (!hasUpper) {
chars.add(ALPHABETIC_UPPERCASE_SYMBOLS.charAt(RandomUtils.nextInt(0, ALPHABETIC_UPPERCASE_SYMBOLS.length())));
hasUpper = true;
} else if (!hasLower) {
chars.add(ALPHABETIC_LOWERCASE_SYMBOLS.charAt(RandomUtils.nextInt(0, ALPHABETIC_LOWERCASE_SYMBOLS.length())));
hasLower = true;
} else if (!hasNumber) {
chars.add(NUMERIC_SYMBOLS.charAt(RandomUtils.nextInt(0, NUMERIC_SYMBOLS.length())));
hasNumber = true;
} else if (!hasSpecial) {
chars.add(SPECIAL_SYMBOLS.charAt(RandomUtils.nextInt(0, SPECIAL_SYMBOLS.length())));
hasSpecial = true;
} else {
chars.add(ALPHANUMERIC_AND_SPECIAL_SYMBOLS.charAt(RandomUtils.nextInt(0, ALPHANUMERIC_AND_SPECIAL_SYMBOLS.length())));
}
}
// Shuffle characters to mix up the first 4 characters
Collections.shuffle(chars);
return StringUtils.join(chars, "");
}
}
I need a String array with the following attributes:
4 digits numbers
No repeating digits ("1214" is invalid)
No 0's
Is there an easier way to do this than manually type it? Like:
String[] s = {"1234","1235",1236",1237",1238",1239","1243","1245"};
Sorry for my English!
The following code will generate an array with your specifications.
public class Test {
public static void main(String[] args) {
List<String> result = new ArrayList<>();
Set<Character> set = new HashSet<>();
for (int i = 1234; i <= 9876; i++) {
set.clear();
String iAsString = Integer.toString(i);
char[] chars = iAsString.toCharArray();
boolean valid = true;
for (char c : chars) {
if (c == '0' || !set.add(c)) {
valid = false;
break;
}
}
if (valid) {
result.add(iAsString);
}
}
String[] yourStringArray = result.toArray(new String[result.size()]);
System.out.println(Arrays.toString(yourStringArray));
}
}
****edit****
Just saw that it is in Java. So use this function: String.valueOf(number) to convert integer to string if none of the digits are repeats in the loop.
Not sure what language you are doing but I am assuming no repeats not replies.
So what you can do is have a loop from 0 to 9999 and then run through all the numbers while checking if each digit has repeats if so discard number (do not store it into array).
You can convert integers to strings in many languages in their function so you can do that then store it into array.
Good luck.
Hope this helped (fastest solution from my head...there could be more efficient ones)
Try this method for creating Random number with your structure :
ArrayList<Integer> rawNumbers = new ArrayList<Integer>(Arrays.asList(1,2,3,4,5,6,7,8,9));
public String createRandomNumberSring()
{
String result = "";
ArrayList<Integer> numbers = new ArrayList<Integer>();
numbers.addAll(rawNumbers);
for(int i = 0; i < 4; i++)
{
int index = (int)(Math.random() * (numbers.size() + 1));
result += numbers.get(index).toString();
numbers.remove(index);
}
return result;
}