I have an exercise about the analysis of passwords (weak vs strong) and I have to create 2 constructors. One of them must receive the length of a password and the password must be created randomly, how can I do that ?
Also I'm having trouble determining if the password is weak or strong. It's going to be strong if the password has at least 3 uppercase letters, 2 lowercase letters and 6 numbers.
class Password {
private double length;
private String password;
Password()//default constructor with password length 8
{
password="defaultt";
length=8;
}
Password(double length)
{
this.length=length;
password="";//generate a random password, how?
}
boolean isStrong(String password)
{
int totalnumbers=0;
int upper=0;
int lower=0;
for(int i=0;i<password.length;i++)//marks an error in .length why?
{
if (password.charAt(i)>='0' && password.charAt(i)<='9')
totalnumbers+=1;
if (password.charAt(i) is lowercase)//what can I do here?
lower+=1;
if (password.charAt(i) is uppercase)
upper+=1;
}
if(totalnumbers>=6 && lower>=2 && upper>=3)
return true;
else
return false;
}
generatePassword(double length)
{
password;//generate the password of the object with this.length //how to do it?
}
String getPassword()
{
return password;
}
double getLength()
{
return length;
}
void setLength(double length)
{
this.length=length;
}
}
public class Exercises2 {
public static void main(String[] args) {
Password x=new Password();
Password array[];
Scanner rd=new Scanner(System.in);
int Size;
System.out.println("Give the size of the passwords array ");
Size=rd.nextInt();
array=new Password[Size];
for( int i=0;i<Size;i++)
{
array[i]=new Password();//creation of an object for each position of the array
}
for(int j=0;j<Size;j++)
{
System.out.println("Give the size for each password of the array ");
array[j]=[rd.nextInt]; //length for each password of the array
}
Password arrayBooleans[]=new Password[Size];
for (int k=0;k<Size;k++){
arrayBooleans[k]=x.isStrong(array[k]);
}
for(int i=0;i<Size;i++)
{
System.out.println("password "+i+ arrayBooleans[i]);
}
}
}
First, you shouldn't use a double for the number of characters in the password. How could you have 1.5 characters? Just use an int.
To check if a character is a digit, lower case or upper case, use the Character class (don't rely on ASCII values):
for (int i = 0; i < password.length(); i++) {
Character c = Character.valueOf(password.charAt(i));
if (c.isDigit()) {
totalnumbers++;
}
if (c.isLowerCase()) {
lower++;
}
if (c.isUpperCase()) {
upper++;
}
}
To generate a random alphanumeric string of a given length, take a look at the accepted answer for this SO post. There are many different ways to do it, but this is as good a place as any to start.
You have a few different questions here, so I'll do my best to answer them all:
Random password:
This SO question talks about random password generation, so for more details, look into what is posted there, but essentially you need to use some random generation that is built into Java and create a string out of it. There are many different ways to do it, which is detailed in that question, so I'll leave that to you to decide how you wish to do it.
Error in for loop:
Calling password.length tries to access a variable called length in the password object. In Java, you can't do that, you must use the method:
password.length()
Uppercase/lowercase detection
This SO question shows a good way to detect if a character is uppercase or lowercase based on its char value. Snippet:
if(input>='a'&&input<='z')
//lowercase
if(input>='A'&&input<='Z')
//uppercase
Try to use the simple logic,
Use Password()
{
// Simply check length
if(length == 8)
{
// Call a method which would check that password is strong or weak. for e.g,
}
}
// You can use the class java.util.Random with method to generate the password
for e.g,
char c = (char)(rnd.nextInt(128-32))+32
20x to get Bytes, which you interpret as ASCII. // If you're fine with ASCII.
// Call a method which would check that password is strong or weak.
Use the given link for random generation of password:
Creating a random string with A-Z and 0-9 in Java
http://www.baeldung.com/java-random-string
Related
I am writing a hangman program and one of the requirements to a hangman game is preventing the user from entering the same letter twice.
I have written the code for that, but the problem is every time I enter a letter it says it is already entered. I need to only say it when it is entered the second time. You guys have any suggestions? I've been trying to fix this for the past few hours, I figured I could ask on here to find some help. I already looked at another Stackoverflow question regarding something similar to this but all those solutions have the same result.
In Java, how can I determine if a char array contains a particular character?
I've tried something like this but it won't work either:
boolean contains = false;
for (char c : store) {
if (c == character) {
System.out.println("Already Entered");
contains = true;
break;
}
}
if (contains) {
// loop to top
continue;
}
SECOND CLASS-
public void hangman(String word, int life) {
KeyboardReader reader = new KeyboardReader();
char[] letter = new char[word.length()];
char[] store = new char[word.length()];
String guess;
int i = 0, tries = 0, incorrect = 0, count = 1, v = 0;
while (i < word.length()) {
letter[i] = '-';
I would just use the String.contains() method:
String aString = "abc";
char aChar = 'a';
return aString.contains(aChar + "");
To keep track of guessed letters you can use a StringBuffer, appending them using a StringBuffer.append() to append new letters (maintaining state) and use the StringBuffer.toString() method to get the String representation when you need to do the comparison above.
Since Java 1.5 the class String contains the method contains(). My idea is to collect all entered letters into a string variable and using above method:
// My code line
String letterAlreadyEntered = "";
// Your code line
char character = reader.readLine().charAt(0);
// My code line
if (letterAlreadyEntered.contains("" + character) == true) {
//Put code here what ever you want to do with existing letter
} else {
letterAlreadyEntered += character;
}
In my opinion, this is an easier way to check for occurrences than in arrays, where you have to write your own check method.
I am trying to get my code to prevent a user input from having a number in it.
Essentially I want the code to do as follows:
ask for input
receive input
test whether or not the input contains a number(ex: 5matt vs matt)
if contains a number I want to System.out.println("Error: please do not input a number");
Heres the kicker (and why it's not a duplicate question): I can't use loops or other statements we haven't learned yet. So far the only true statements we've learned are if/else/else if statements. That means I can not use for loops, like some of the answers are suggesting. While they're great answers, and work, I'll lose points for using them.
System.out.println("Please input the first name: ");
String name1 = in.next();
System.out.println("Please input the second name: ");
String name2 = in.next();
System.out.println("Please input the third name: ");
String name3 = in.next();
name1 = name1.substring(0,1).toUpperCase() + name1.substring(1).toLowerCase();
name2 = name2.substring(0,1).toUpperCase() + name2.substring(1).toLowerCase();
name3 = name3.substring(0,1).toUpperCase() + name3.substring(1).toLowerCase();
I have this already but I can't figure out how to test if the input only contains letters.
Okay, there are many ways to deal with this. A good thing would be to use Regex (text matching stuff). But it seems that you should only use very basic comparison methods.
So, let's do something very basic and easy to understand: We iterate over every character of the input and check whether it's a digit or not.
String input = ...
// Iterate over every character
for (int i = 0; i < input.length(); i++) {
char c = s.charAt(i);
// Check whether c is a digit
if (Character.isDigit(c)) {
System.out.println("Do not use digits!");
}
}
This code is very straightforward. But it will continue checking even if a digit was found. You can prevent this using a helper-method and then returning from it:
public boolean containsDigit(String text) {
// Iterate over every character
for (int i = 0; i < input.length(); i++) {
char c = s.charAt(i);
// Check whether c is a digit
if (Character.isDigit(c)) {
return true;
}
}
// Iterated through the text, no digit found
return false;
}
And in your main program you call it this way:
String input = ...
if (containsDigit(input)) {
System.out.println("Do not use digits!");
}
Use a regular expression to filter the input
Eg
str.matches(".*\\d.*")
See this link for more info
There are several ways you could do this, among others:
Iterate over all the chars in the string and check whether any of them is a digit.
Check whether the string contains the number 1, number 2, number 3, etc.
Use a regular expression to check if the string contains a digit.
(Java Regular Expressions)
If you're allowed to define functions, you can essentially use recursion to act as a loop. Probably not what your prof is going for, but you could be just inside the requirements depending on how they're worded.
public static boolean stringHasDigit(String s) {
if (s == null) return false; //null contains no chars
else return stringHasDigit(s, 0);
}
private static boolean stringHasDigit(String s, int index) {
if (index >= s.length()) return false; //reached end of string without finding digit
else if (Character.isDigit(s.charAt(index))) return true; //Found digit
else return stringHasDigit(s, index+1);
}
Only uses if/elseif/else, Character.isDigit, and String.charAt, but recursion might be off limits as well.
What I have is a program that reads in a user-entered phone number and returns the country code (if it exists), area code (if it exists), and local 7-digit phone number.
The number must be entered as countrycode-area-local. So, the maximum number of dashed you can have in the phone number is two.
For example:
1-800-5555678 has two dashes (it has a country code and area code)
800-5555678 has one dash (it only has an area code)
5555678 has no dashes (only local number)
So, it's OK to have zero dashes, one dash, or two dashes, but no more than two.
What I am trying to figure out is how you would count the number of dashes ("-") in the string to make sure there aren't more than two instances of them. If there are, it would print an error.
So far, I have:
if(phoneNumber ///contains more more than two dashed
{
System.out.println("Error, your input has more than two dashes. Please input using the specified format.");
{
else
{
//normal operations
}
Everything works so far except for this one part. I'm not sure what method to use to do this. I tried looking at indexOf, but I am stumped.
One way do it would be to parse the number into string and then split on the dashes. If the new array you get is of length greater than 3 then give an error.
String s = "1-800-5555678";
String parts[] = s.split("-");
if (parts.length > 3) {
System.out.println("error");
} else {
// do something
}
A more memory efficient solution as suggested by samrap is:
String s = "1-800-555-5678";
int dashes = s.split("-").length - 1;
if (dashes > 2) {
System.out.print("error");
} else {
// do something
}
String phoneNumber = "1-800-5555678";
int counter = 0;
for( int i=0; i< phoneNumber.length(); i++ ) {
if( phoneNumber.charAt(i) == '-' ) {
counter++;
}
}
if(counter > 2) ///contains more more than two dashed
{
System.out.println("Error, your input has more than two dashes. Please input using the specified format.");
{
else
{
//normal operations
}
Something like this. Loop through the chars in the string and see if they are -
int nDashes = 0;
for (int i=0; i<phoneNumber.length(); i++){
if (phoneNumber.charAt(i)=='-')
nDashes++;
}
if (nDashes>2){
//do something
}
Regex and replaceAll() are your friends. Use,
int count=string.replaceAll("\\d","").length();
This will replace all the numbers with empty strings and thus all you will be left with is -s
I have 2 strings "test" "bet" and another string a="tbtetse". I need to check if the "tbtetse" contains the other two strings.
I was thinking if I could find all the anagrams of string a and and then find the other two strings in those, but it doesn't work that way and also my anagram code is failing for a lengthy string.
Could you please help with any other ways to solve it?
Assuming you're trying to test whether the letters in a can be used to form an anagram of the test strings test and bet: I recommend making a dictionary (HashMap or whatever) of character counts from string a, indexed by character. Build a similar dictionary for the words you're testing. Then make sure that a has at least as many instances of each character from the test strings as they have.
Edit: Alcanzar suggests arrays of length 26 for holding the counts (one slot for each letter). Assuming you're dealing with only English letters, that is probably less of a hassle than dictionaries. If you don't know the number of allowed characters, the dictionary route is necessary.
Check below code, it may help you.
public class StringTest {
public static void main(String[] args) {
String str1 = "test";
String str2 = "bev";
String str3 = "tbtetse";
System.out.println(isStringPresent(str1, str2, str3));
}
private static boolean isStringPresent(String str1, String str2, String str3) {
if ((str1.length() + str2.length()) != str3.length()) {
return false;
} else {
String[] str1Arr = str1.split("");
String[] str2Arr = str2.split("");
for (String string : str1Arr) {
if (!str3.contains(string)) {
return false;
}
}
for (String string : str2Arr) {
if (!str3.contains(string)) {
return false;
}
}
}
return true;
}
}
basically you need to count characters in both sets and compare them
void fillInCharCounts(String word,int[] counts) {
for (int i = 0; i<word.length(); i++) {
char ch = word.charAt(i);
int index = ch - 'a';
counts[index]++;
}
}
int[] counts1 = new int[26];
int[] counts2 = new int[26];
fillInCharCounts("test",counts1);
fillInCharCounts("bet",counts1);
fillInCharCounts("tbtese",counts2);
boolean failed = false;
for (int i = 0; i<counts1.length; i++) {
if (counts1[i] > counts2[i]) {
failed = true;
}
}
if (failed) {
whatever
} else {
something else
}
If you are generalizing it, don't forget to call .toLowerCase() on the word before sending it in (or fix the counting method).
Pseudo code:
Make a copy of string "tbtetse".
Loop through each character in "test".
Do a indexOf() search for the character in your copied string and remove it if found.
If not found, fail.
Do the same for the string "bet".
class WordLetter {
char letter;
int nth; // Occurrence of that letter
...
}
One now can use Sets
Set<WordLetter>
// "test" = { t0 e0 s0 t1 }
Then testing reduces to set operations. If both words need to be present, a union can be tested. If both words must be formed from separate letters, a set of the concatenation can be tested.
I have to implement a Java method, which will determine, if a input string is a hash (generated by a machine) or a plain-text (written by a human).
Example:
isThisEncrypted("qwertyuiopasdfghjklzxcvbnm"); // returns true
isThisEncrypted("some normal human text"); // returns false
I thought about using the Kolmogorov-Smirnov test (jsc.goodnessfit.KolmogorovTest), which will check, if a characters in a string are from normal distribution, but I have learned, that checking only one, short string might not be conclusive.
Do you have any idea how to solve this problem in Java (preferably using a existing library)?
From your comments:
human input can be random
this method has to determin, if string comes from this method or form
user
Then there's no way to solve your problem having just the String. You need extra information.
If you're expecting Blowfish to return a String in a given format, then you're wrong. Modern encryption algorithms target high entropy, which means they have to look and feel like random.
You have stated that you only want an approximate solution (80% accuracy), that classes of the form AClassName are likely (note capitalisation) and the given sample of encrypted text has no capitals in it. So
public class Test{
public static void main(String args[]){
String[] tests=new String[5];
tests[0]="MyClass";
tests[1]="Short";
tests[2]="thsrjtyzfgnmytkzrhjstk";
tests[3]="tatm";
tests[4]="The result is good";
for(int i=0;i<tests.length;i++){
System.out.println(tests[i]+ "- Encrypted:" + isProbablyEncrypted(tests[i]));
}
}
public static boolean isProbablyEncrypted(String in){
int noOfWords= countOccurrences(in, ' ') + countCaps(in);
if (noOfWords==0){
return true;
}else{
double averageWordLength=(double)(in.length())/(noOfWords+1);
if (averageWordLength>15){
return true;
}else{
return false;
}
}
}
public static int countOccurrences(String haystack, char needle)
{
int count = 0;
for (int i=0; i < haystack.length(); i++)
{
if (haystack.charAt(i) == needle)
{
count++;
}
}
return count;
}
public static int countCaps(String in){
int caps=0;
for (int i=0; i<in.length(); i++) {
if (Character.isUpperCase(in.charAt(i)))caps++;
}
return caps;
}
}
Is this a good solution; no, does it give >80% accuracy; yes
You split your input into words and check them against a dictionary ( checking words in a dictionary ) .
From now on everything depends on your implementation. IMO, if half the words match with the dictionary, then your method should return false.