I just need a password generator with special requirements.
I did this code. It works very well but how to take from this String-only 2 special character;-only 2 digits;-only 3 characters in lowercase;-only 3 characters in uppercase.
private static void passGenerator(){
int length = 8;
String symbol = "-/.^&*_!#%=+>)";
String cap_letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String small_letter = "abcdefghijklmnopqrstuvwxyz";
String numbers = "0123456789";
String finalString = cap_letter + small_letter +
numbers + symbol;
Random random = new Random();
char[] password = new char[length];
for (int i = 0; i < length; i++)
{
password[i] = finalString.charAt(random.nextInt(finalString.length()));
}
System.out.println(password);
}
You could try this library by apache. There are some useful methods for split string to array by characters with different cases, by different characters at all (a3 will be a, 3)
I would first generate the password in a specific order and store it in a temporary variable, say like this:
{ special1, special2, digit1, digit2, lower1, lower2, lower3, upper1, upper2, upper3}
This would likely need to be hard coded.
Next, I would create a new password variable, and one by one choose a character and add it to the new variable. Do this by randomly generating a number [0, temp.length). Then, copy the char at that index to the lowest unfilled spot in the new password, remove it from the temp, and copy all the remaining chars to a new temp array one element smaller. Repeat until the temp array size is zero.
Related
This question already has answers here:
Using Regex to generate Strings rather than match them
(12 answers)
Closed 9 months ago.
This post was edited and submitted for review 9 months ago and failed to reopen the post:
Original close reason(s) were not resolved
I am trying to write a program that would ask the user how many security codes he wants to generate, then it would output as many codes as he requested in an array.
The security code should be 7 characters long and have the following format: NNNNLLL, where N is a random number and L is a random upper case letter.
The method should create security codes with the above format by randomly selecting the characters, i.e. numbers and letters.
I am expecting the program to output something like this if a user selects to generate 4 codes:
“2394QAB”
“2821TSZ”
“7173AAY”
“2236WQA”
I can only use the methods for this code learned in my course and I cannot use other libraries like regex, that is why I am trying it like this.
This is the code I have done so far:
import java.util.Random;
public class ItemChecker{
private StringBuffer strBuff;
private String[] codes;
private String CodeLetters, CodeNumbers;
private int[] RandomNums;
public ItemChecker(){
strBuff=new StringBuffer();
}
public String[] getCodes(int[] amount){
codes=new String[amount.length];
for(int i=0;i<amount.length;i++)
{
CodeLetters="";
strBuff=new StringBuffer();
for(int j=0;j<4;j++)
{
Random RandomNumber=new Random();
int randomIndex=RandomNumber.nextInt(RandomNums.length);
CodeNumbers.append(RandomNumber[randomIndex]);
}
for(int j=0;j<3;j++)
{
Random RandomLetter=new Random();
char c =(char)(RandomLetter.nextInt(26)+'a');
CodeLetters+=c;
}
codes[i]=CodeNumbers+CodeLetters;
}
}
}
My intention is to create 4 random digits and 3 random letters and add them together in a string to make the code. However, the code doesn't generate the random codes and I have no clue how to proceed from here.
Within your getCodes method there are a couple of mistakes. A StringBuiler would be more appropriate for this task, instead of using a StringBuffer or chaining strings with the + operator. As a matter of fact, each time you're performing a concatenation with the + operator you're creating a new string in memory, rather than working on a same instance, this is not that efficient. Also, when you're adding an offset to the random value representing an upper case letter, you're adding the lower case 'a', instead of the upper case 'A'.
In your program, you could define a static method to offer the code generation service as a general utility and then invoke it within your getCodes method.
In the utility method, you could declare a Random object to get random int values. Then, with a first for loop, you could generate random values between 0 included and 10 excluded, and append them to a StringBuilder object. The String class represents immutable objects, so you need to use a StringBuilder to build one. As said above, chaining strings with the + operator will create new instances at each concatenation, you're not working on the same object.
Then, with a second for loop you could generate random values from 0 to 27 excluded, add to every value the offset 65, representing the upper case 'A' letter (lower case 'a' has value 97), and then cast this int value to a char to get its character representation. Finally, append the char to your StringBuilder instance.
Here is an implementation:
public class Main {
public static void main(String[] args) {
System.out.println(getSecurityCode());
}
public String[] getCodes(int[] amount) {
String[] codes = new String[amount.length];
for (int i = 0; i < codes.length; i++) {
codes[i] = getSecurityCode();
}
return codes;
}
public static String getSecurityCode() {
Random rand = new Random();
StringBuilder strBuilder = new StringBuilder();
//Appending 4 random digits
for (int i = 0; i < 4; i++) {
//nextInt(10) returns a value between 0 (included) and 10 (excluded)
strBuilder.append(rand.nextInt(10));
}
//Appending 3 random upper case letters
for (int i = 0; i < 3; i++) {
//rand.nextInt(27) returns a random value between 0 and 26 included to represent an alphabet letter.
//This value is added with the offset 65 which represents the upper case A letter.
//Finally, this value is cast as a char or else it would append its int value
strBuilder.append((char)(65 + rand.nextInt(27)));
}
return strBuilder.toString();
}
}
To simplify your code that generate the password you could use RandomStringUtils from org.apache.commons.lang3.RandomStringUtils like described in this great tutorial https://www.baeldung.com/java-random-string.
You just have to generate 2 strings :
One with 4 digits
One with 3 letters to uppercase
And concat both.
Here's How
public static String getSecurityCode() {
//generate 4 numbers only
String generatedNumbers = RandomStringUtils.random(4, false, true);
//generate 3 letters only
String generatedLetters = RandomStringUtils.random(3, true, false).toUpperCase();
return generatedNumbers + generatedLetters;
}
Or with StringBuilder
public static String getSecurityCode2() {
StringBuilder stb=new StringBuilder(7);
//generate 4 numbers only
stb.append(RandomStringUtils.random(4, false, true));
//generate 3 letters only
stb.append( RandomStringUtils.random(3, true, false).toUpperCase());
return stb.toString();
}
Another way of doing this is to utilize StringBuilder's appendCodePoint method for this:
int number= random.nextInt(10000); //generate any number between 0 to 9999
StringBuilder builder=new StringBuilder();
for(int i=0;i<3;i++) {
builder.appendCodePoint(65+random.nextInt(26));
}
String result=number+builder.toString();
System.out.println(result);
How to delete the characters at x and keep the rest? The output should be "12345678" Deleting every '9' in the position that x is on. X is i*(i+1)/2 so that the number is added to the next number. So every number at 0,1,3,6,10,15,21,28,etc.
public class removeMysteryI {
public static String removeMysteryI(String str) {
String newString = "";
int x=0;
for(int i=0;i<str.length();i++){
int y = (i*(i+1)/2)+1;
if(y<=str.length()){
x=i*(i+1)/2;
newString=str.substring(0, x) + str.substring(x + 1);
}
}
return newString;
}
public static void main(String[] args) {
String str = "9919239456978";
System.out.println(removeMysteryI(str));
}
}
OK, so there are a couple of mistakes in your code. One is easy to fix. The others not so easy.
The easy one first:
newString=str.substring(0, x) + str.substring(x + 1);
OK so that is creating a string with the character at position x removed. The problem is what it is operating on. The str variable is the input parameter. So at the end of the day newString will still only be str with one character removed.
The above actually needs to be operating on the string from the previous loop iterations ... if you are going to remove more than one character.
The next problem arises when you try to solve the first one. When you remove a character from a string, all characters after the removal point are renumbered; e.g. after removing the character at 5, the character at 6 becomes the character at 5, the character at 7 becomes the character at 6, and so on.
So if you are going to remove characters by "snipping" the string, you need to make sure that the indexes for the positions for the "snips" are adjusted for the number of characters you have already removed.
That can be done ... but you need to think about it.
The final problem is efficiency. Each time your current code removes a single character (as above), it is actually copying all remaining characters to a new string. For small strings, that's OK. For really large strings, the repeated copying could have a serious performance impact1.
The solution to this is to use a different approach to removing the characters. Instead of snipping out the characters you want to discard, copy the characters that you want to keep. The StringBuilder class is one way of doing this2. If you are not permitted to use that, then you could do it with an array of char, and an index variable to keep track of your "append" position in the array. Finally, there is a String constructor that can create a String from the relevant part of the char[].
I'll leave it to you to work out the details.
1 - Efficiency could be viewed as beyond the scope of this exercise.
2 - #Horse's answer uses a StringBuilder but in a different way to what I am suggesting. This will also suffer from the repeated copying problem because each deleteCharAt call will copy all characters after the deletion point.
Follow the steps below:
Initialize with builderIndexToDelete = 0
Initialize with counter = 1
Repeat the following till the index is valid:
delete character at builderIndexToDelete
update builderIndexToDelete to counter - 1 (-1 as a character is deleted in every iteration)
increment the counter
public static String deleteNaturalSumIndexes(String str) {
StringBuilder builder = new StringBuilder(str);
int counter = 1;
int builderIndexToDelete = 0;
while (builderIndexToDelete < builder.length()) {
builder.deleteCharAt(builderIndexToDelete);
builderIndexToDelete += (counter - 1);
counter++;
}
return builder.toString();
}
public static void main(String[] args) {
String str = "9919239456978";
System.out.println(deleteNaturalSumIndexes(str));
}
Thank you #dreamcrash and #StephenC
Using #StephenC suggestion to improve performance
public static String deleteNaturalSumIndexes(String str) {
StringBuilder builder = new StringBuilder();
int nextNum = 1;
int indexToDelete = 0;
while (indexToDelete < str.length()) {
// check whether this is a valid range to continue
// handles 0,1 specifically
if (indexToDelete + 1 < indexToDelete + nextNum) {
// min is used to limit the index of last iteration
builder.append(str, indexToDelete + 1, Math.min(indexToDelete + nextNum, str.length()));
}
indexToDelete += nextNum;
nextNum++;
}
return builder.toString();
}
public static void main(String[] args) {
System.out.println(deleteNaturalSumIndexes(""));
System.out.println(deleteNaturalSumIndexes("a"));
System.out.println(deleteNaturalSumIndexes("ab"));
System.out.println(deleteNaturalSumIndexes("abc"));
System.out.println(deleteNaturalSumIndexes("99192394569"));
System.out.println(deleteNaturalSumIndexes("9919239456978"));
}
Well i'm trying to get a String from user and change each letter to the String "enc" I have down here. So basically if the user input "hello" I want it to return back "xahhi". I am kind of lost and don't know what to do.
String userInput = input.nextLine();
String letters = "abcdefghijklmnopqrstuvwxyz";
String enc = "kngcadsxbvfhjtiumylzqropwe";
int stringLength = userInput.length();
for (int i = 0; i < stringLength; i++) {
if (userInput.charAt(i) == letters.charAt(i)) {
System.out.print(enc.charAt(i));
}
}
What you want to do is have a Map<Character,Character> where key will be correct Character that in the String and the value should be Character that is encoded.
Then you query the Map for the encoding an generate you encoded string.
Code should look like :
Map<Character,Character> myEncodingMap = new HashMap<Character,Character>();
StringBuilder sb = new StringBuilder();
for (Character ch : letters.toCharArray()) {
sb.append(myEncodingMap.get(ch)
}
System.out.print(sb.toString());
Here is one that might be a little simpler if you are just starting out in programming. I have explained what each line does in the code so take a look and try to understand and expand on it! Let me know what you think or if you have any questions.
import java.util.Scanner;
public class main {
public static void main(String[] args) {
char[] letters = "abcdefghijklmnopqrstuvwxyz".toCharArray(); //Just takes the String and puts it into a array of chars
char[] enc = "kngcadsxbvfhjtiumylzqropwe".toCharArray();
Scanner scan = new Scanner(System.in); //Scanner for user input
System.out.println("enter phrase"); //prompts for user input
String input = scan.next(); //Takes user input and stores it in String input
for(int i = 0; i<input.length(); i++){
char temp = input.charAt(i); //Stores the first Character of the entered phrase in a variable called temp.
int tempNums = (new String(letters).indexOf(temp)); //takes the position in the first array of the first char entered and stores it.
System.out.print(new String(enc).charAt(tempNums)); //prints out the values of the first character according to the second array.
}
}
}
If you want to use String methods only, you're close. However, you need to use two methods from the String class to finish this: indexOf(char) and charAt(int).
indexOf(char) takes a character and returns the index of the first location it appears in the string. For example, if you have a string with contents Hello World, then str.indexOf('l') will return 2, which is the first index in the string that matches the given character.
charAt(int) takes an integer and returns the character in a string at the given index. For example, using the same string as above, calling str.charAt(4) will return 'o'.
Using these two methods can get you an index of one string which you can then use to reference the character of the other.
I'm not going to put the answer in your code (you should learn enough to be able to do it yourself), but I'll give you a skeleton of how I would do this using just the two methods above.
// The two strings used for encoding
String strNormal = "ABCDEF";
String strCode = "UVWXYZ";
// The example string that is input by the user
String input = "BED";
/*** NOTE: This only replaces the first letter of the input string ***/
// Get the first character of the input string
char originalChar = input.charAt(0);
// Get the index of of the corresponding character in the normal string
int searchIndex = strNormal.indexOf(originalChar);
// Get the corresponding character of the encoder string
char encodedChar = strCode.charAt(searchIndex);
// Print out the encoded letter
System.out.print(encodedChar);
Though this approach will work, there are some caveats. The biggest one is performance: Every time you call indexOf or charAt, Java loops through the entire string to find what you're looking for. This isn't a problem for small strings like you'll be dealing with, but imagine a string that's maybe 10,000 characters long... It's possible that you'd have to search every letter in that string 10,000 times! Not super efficient.
OK so I'm trying to design a simple program that checks to see if a substring of length 4 characters is within all initial strings. Here is my code as follows:
public class StringSearch{
private String[] s1Array = {"A","C","T","G","A","C","G","C","A","G"};
private String[] s2Array = {"T","C","A","C","A","A","C","G","G","G"};
private String[] s3Array = {"G","A","G","T","C","C","A","G","T","T"};
//{for (int i = 0; i < s1Array.length; i++){
// System.out.print(s1Array[i]);
//}}//check if Array loaded correctly
/**
* This is the search method.
*
* #param length length of sub string to search
* #param count counter for search engine
* #param i for-loop counter
* #return subStr returns strings of length = 4 that are found in all 3 input strings with at most
* one mismatched position.
*/
public String Search()
{
int length = 4;
int count = 0;
int i = 0;
ArrayList<StringSearch> subStr = new ArrayList<StringSearch>();
//String[] subStr = new String[4];
do
{
for (i = count; i < length; i++){
subStr.add(s1Array[i]); // cant find .add method???
count = count + 1;
}
if (s2Array.contains(subStr) && s3Array.contains(subStr)){ //can't find .contains method???
System.out.println(subStr + "is in all 3 lists.");
}
if (count = s1Array.length){
System.out.println("Task complete.");
}
else{
count = count - length;
count = count + 1;
}
}while (count <= s1Array.length);
}
}
For some reason, Java cannot seem to find the .add or .contains methods and I have no idea why. So my approach was to turn the initial Strings each into an array (since the assignment specified each string would be exactly N elements long, in this case N = 10) where 1 letter would be 1 element. The next thing I did was set up a for loop that would scan s1Array and add the first 4 elements to an ArrayList subStr which is used to search s2Array and s3Array. Here is where .add isn't a valid method, for whatever reason. Commenting that out and compiling again, I also ran into an issue with the .contains method not being a valid method. Why won't this work? What am I missing? Logically, it seems to make sense but I guess maybe I'm missing something in the syntax? Help would be appreciated, as I'm a Java novice.
There are lots of errors and misunderstandings here.
Let's start with #1
private String[] s1Array = {"A","C","T","G","A","C","G","C","A","G"};
Making an array of strings is just silly, you should either use a single string or an array of characters.
private String s1 = "ACTGACGCAG";
Or
private char[] s1Array = {'A','C','T','G','A','C','G','C','A','G'};
Now #2
ArrayList<StringSearch> subStr = new ArrayList<StringSearch>();
This means you are trying to make an ArrayList that contains objects of type StringSearch. StringSearch is a class that contains your three arrays and your Search function so I don't think this is what you want.
If you wanted to make a list of 3 strings you might do something like this:
ArrayList<String> stringList = new ArrayList<String>();
stringList.add(s1);
stringList.add(s2);
stringList.add(s3);
Now say you defined s1, s2 and s3 as strings you can do something like this.
for(int i = 0; i <= s1.length() - 4; i++)
{
String subStr = s1.substring(i, i + 4);
if(s2.contains(subStr) && s3.contains(subStr))
{
System.out.println(subStr + " is in all 3 lists.");
}
}
System.out.println("Task Complete.");
The above code should achieve what it looks like you are trying to do. However, it should be noted that this isn't the most efficient way, just a way, of doing it. You should start with some more basic concepts judging by the code you have so far.
After declaring subStr as ArrayList you can call add or contains only with StringSearch objects as parameters.
Instead of:
ArrayList<StringSearch> subStr = new ArrayList<StringSearch>();
Replace it with:
String subStr = "";
And within the for loop to get the first 4 letters in s1 to be in its own string (subStr) add the line:
subStr += s1Array[i];
Also, s1Array is a String array, and not a String. The .contains method is a method that belongs to String variables, so for eg. the way you have it implemented, you can say s1Array[i].contains. But you cannot say s1Array.contains. If you change your String arrays to Strings and edit your code to suit, everything should work the way you expect it to work.
First of all you need to educate yourself on the concept of Java generics.
The most basic thing about generics is that once you declare a collection, here it is the arraylist, as you can only add objects of StringSearch.
Second of all, logically what you can do is to implement an algorithm called
Longest Common Subsequence. Check in pairs whether the longest subsequeces are 4 or not on the arrays.
I've tried the code below, but I'm getting an error. How would I go about adding two large values represented as strings together?
public class LargeAddition {
static String testcase1 = "987659876598765";
static String testcase2 = "9999999999999999999999999988888888888";//can we add this kind of large num
public static void main(String args[]){
LargeAddition testInstance = new LargeAddition();
String result = testInstance.add(testcase1,testcase2);
System.out.println("Result : "+result);
}
//write your code here
public String add(String str1, String str2){
Long num=000000000000000L;
//String str="";
num=Long.parseLong(str1)+Long.parseLong(str2);
//String str=num.toString();
return num.toString();
}
}
Use BigInteger, Long is short for these values.
public static String add(String str1, String str2) {
BigInteger big1 = new BigInteger(str1);
BigInteger big2 = new BigInteger(str2);
final BigInteger num = big1.add(big2);
return num.toString();
}
Since this is an a homework assignment and you don't/can't use classes such as BigInteger, I'll go through a more tedious and manual way to do it (although a good introduction assignment).
You can loop through the two String-integers from size-1 to 0.
String integer1 = "1230"
String integer2 = "9999999"
for(int i = integer1.size; i >= 0; i--){
//addition
}
However, this is may be an issue since the two String-integers have different sizes. I would create a method that will add additional zeroes to the front of the smaller String-integer so both String-integers match in size. Ex. "1230" -> "0001230"
Before looping, create an output String-inter which equals to an empty-String.
String outputInt = "";
Convert each char to an int, then do the addition.
int tempResult = Integer.parseInteger(integer1.indexOf(i)) + Integer.parseInteger(integer2.indexOf(i))
If you get a single digit, convert it to a String and append to output String-integer. If you get a double digit, then only put append the second digit and carry over the first digit to the next calculation.
String tempResultStr = //convert tempResult into a String
if(tempResultStr .size == 1){
//handle single digit case
}else{
//handle double digit case
//use a variable to declare carry over
}
Remember to handle the case if you have to carry over and there is nothing to carry over to.
NOTE: This is pseudo code for most part
If you run
System.out.println(Long.MAX_VALUE);
you'll get
9223372036854775807
your values are far greater
9999999999999999999999999988888888888
so the way is to use BigDecimal
BigDecimal bd = new BigDecimal("9999999999999999999999999988888888888");
System.out.println(bd.multiply(bd));
gives you
99999999999999999999999999777777777760000000000000000123456790143209876544