How to obscure Scanner input text? [duplicate] - java

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Hide input on command line
I'm making a password security checker program and my question is odd in that my program runs just fine. What I'm wondering is whether there is any way of making text entered to the console appear as it would in a password field. i.e the word entered will appear as "****" BEFORE the user presses the return key.
I am aware that JFrame has a JPasswordField method but I don't think that helps me when in just using Scanner.
Here is my code:
import java.util.Scanner;
public class SecurityCheckerMain {
static String enteredPassword;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Please enter your password: ");
enteredPassword = input.nextLine();
Checker tc = new Checker(enteredPassword);
tc.checkSecurity();
}
}
public class Checker {
//number of chars : the Higher the Better("password must be greater than 8 chars"){done}
//combination of uppercase and lowercase{done}
//contains numbers{done}
//non repeated characters (every char is different ascii char){done}
//is not a consecutive password ie 123456789 or 987654321{done}
//is not blank ("[space]"){done}
int pLength;
final int MAX_STRENGTH = 10;
int pStrength = 0;
String pass;
public Checker(String pwd){
pass = pwd;
pLength = pwd.length();
}
public void checkSecurity(){
if(pass.isEmpty()){
System.out.println("Password Field is Empty! Password is Very Insecure.");
}
if(pLength >= 8){
pStrength++;
if(pLength >= 12){
pStrength++;
if(pLength >= 16){
pStrength++;
}
}
}
if(hasUpperCase(pass) && hasLowerCase(pass)){
pStrength+=2;
}
if(containsNumbers(pass)){
pStrength+=2;
}
if(hasNoRepeats(pass)){
pStrength+=2;
}
if(!containsConsecutiveNums(pass)){
pStrength++;
}
System.out.println("Your password strength is rated at " + pStrength +"/" + MAX_STRENGTH);
}
//Component Methods
public boolean hasUpperCase(String str){
for(int i = 0; i<pLength; i++){
if(Character.isUpperCase(str.charAt(i))){
return true;
}
}
return false;
}
public boolean hasLowerCase(String str){
for(int i = 0; i<pLength; i++){
if(Character.isUpperCase(str.charAt(i))){
return true;
}
}
return false;
}
public boolean containsNumbers(String str){
for(int i = 0; i<pLength; i++){
if(Character.isDigit(str.charAt(i))){
return true;
}
}
return false;
}
public boolean hasNoRepeats(String str){
for(int i = 0; i<pLength; i++)
if(containsChar(str, str.charAt(i))){
return false;
}
return true;
}
public boolean containsChar(String s, char search) {
if (s.length() == 0)
return false;
else
return s.charAt(0) == search || containsChar(s.substring(1), search);
}
public boolean containsConsecutiveNums(String str){
for(int i = 0; i<pLength; i++){
if(Character.isDigit(str.charAt(i))){
if(str.charAt(i)-1 == str.charAt(i-1) || str.charAt(i)+1 == str.charAt(i+1)){
return true;
}
}
}
return false;
}
}

You can use Console.readPassword instead.
readPassword(String fmt, Object... args)
Provides a formatted prompt, then reads a password or passphrase from
the console with echoing disabled
public class SecurityCheckerMain {
static String enteredPassword;
public static void main(String[] args) {
Console console = System.console();
enteredPassword =
new String(console.readPassword("Please enter your password: "));
Checker tc = new Checker(enteredPassword);
tc.checkSecurity();
}

Related

How do I capture inputs from a system.out.println to compare if they match? [duplicate]

This question already has answers here:
JUnit test for System.out.println()
(14 answers)
Closed 9 months ago.
I am a first year studying app development and I have a login and registration assignment.
But Im struggling to make a method where it checks if the username and password registered matches the entered login details?
I am mostly using System.out.println
Here is the Login.java
package st10035771;
import java.util.Scanner;
public class Login {
public final static int USERNAME_LIMIT = 5;
public final static int PASSWORD_LENGTH = 8;
private static String userName;
private static String userPass;
private static String message;
private static String firstName;
private static String lastName;
public static Scanner un = new Scanner(System.in);
public static boolean checkUserName(String userName) {
if (userName.length() <= USERNAME_LIMIT && userName.contains("_")) {
return true;
} else {
return false;
}
}
/*
* code attribute
* this code was adapted from DelftStack
* https://www.delftstack.com/howto/java/password-checker-java/
*/
public static boolean checkPasswordComplexity(String userPass) {
boolean isValidPassword = false;
final int minUppers = 1;
final int minDigits = 1;
final int minSpecials = 1;
int uppers = 0;
int digits = 0;
int specials = 0;
for (int i = 0; i < userPass.length(); i++) {
char ch = userPass.charAt(i);
if (Character.isUpperCase(ch))
uppers++;
else if (Character.isDigit(ch))
digits++;
// if (ch >= 33 && ch <= 47 || ch == 64) {
if (!Character.isLetterOrDigit(ch)) {
specials++;
}
}
if (userPass.length() >= PASSWORD_LENGTH && uppers >= minUppers && digits >= minDigits
&& specials >= minSpecials) {
return isValidPassword = true;
}
return isValidPassword;
}
public static void inputUser() {
System.out.println("Please enter username:");
setUserName(un.next());
if (checkUserName(userName)) {
System.out.println("Username successfully captured");
} else {
System.out.println(
"Username is not correctly formatted, please ensure that your username contains an underscore and is no more than 5 characters in length.");
}
}
public static void inputFName() {
System.out.println("Please enter your name:");
setFirstName(un.next());
System.out.println("Please enter your surname:");
setLastName(un.next());
}
public static void inputPass() {
System.out.println("Please enter password:");
setUserPass(un.next());
if (checkPasswordComplexity(userPass)) {
System.out.println("Password successfully captured");
} else {
System.out.println(
"Password is not correctly formatted, please ensure that the password contains at least 8 characters, a capital letter, a number and a special character.");
}
}
public static String registerUser() {
if((checkUserName(userName)) == false){
return "Username is not correctly formatted, please ensure that your username contains an underscore and is no more than 5 characters in length.";
}
if((checkPasswordComplexity(userPass)) == false){
return "Password is not correctly formatted, please ensure that the password contains at least 8 characters, a capital letter, a number and a special character";
}
return "Welcome " +firstName+" "+lastName+",it is great to see you.";
}
public boolean loginUser(){
if ((registerUser()) == )
}
/**
* #param aUserPass the userPass to set
*/
public static void setUserPass(String aUserPass) {
userPass = aUserPass;
}
/**
* #param aMessage the message to set
*/
public static void setMessage(String aMessage) {
message = aMessage;
}
/**
* #param aFirstName the firstName to set
*/
public static void setFirstName(String aFirstName) {
firstName = aFirstName;
}
/**
* #param aLastName the lastName to set
*/
public static void setLastName(String aLastName) {
lastName = aLastName;
}
/**
* #param aUserName the userName to set
*/
public static void setUserName(String aUserName) {
userName = aUserName;
}
}
The method in question is loginUser()
You have username and password as userName and userPass data members, respectively, so you will need to pass the textual data you have received from a form and compare it with your data members:
public boolean loginUser(username, password){
if (this.userName.equals(username) && this.userPass.equals(password)) {
//Perform the login
return true;
}
return false;
}
When you call this method, based on the result (true or false you can decide what to print out). Notice that I have a comment which says "perform the login". Since it is unclear how you intend to log in I did not implement it. Note that you have a Login class, which seems to be more like an action and you need a User class. Also, making everything static is an antipattern. So, there are lots of things to improve in your code, but I'm only focusing on the aspect you have been asking the question about.
Also, System.out.println is a way to display your output to the console, you do not need to load anything back from the console. The teacher probably told you that you can output the results using System.out.println, not to read from it.

Method to check "dutch" postal code in java

I'm trying to create a method in java to validate a dutch postal code.
the dutch postal code consist 6 characters which contain 4 numbers (first 4 chars) and 2 letters (last 2 chars) so for example 1010AB.
I made a boolean to return false if the postcode is not within standard and true if it is.
I'm getting stuck with checking the last 2 letters.
I've created a loop for the first 4 numbers, but I don't know how to go further from here to check the letters aswell.
My java method:
public static boolean checkPostcode(String postCode) {
boolean value = false;
if (postCode.length() == lengthPost) {
for (int i = 0; i < postCode.length(); i++) {
if (i <= 4) {
if (Character.isDigit(postCode.charAt(i)) {
value = true;
else{
if (Character.isLetter(postCode.charAt(i))) {
value = true;
}
}
}
}
}
}
return value;
}
You van ignore the last else, because that is the point where I get stuck....
If someone can help me that would be great!!
Thanks in advance
Solution using regex:
public class Main {
public static void main(String[] args) {
// Tests
System.out.println(checkPostcode("1234AB"));
System.out.println(checkPostcode("5678MN"));
System.out.println(checkPostcode("0123AB"));
System.out.println(checkPostcode("1023AB"));
System.out.println(checkPostcode("1230AB"));
System.out.println(checkPostcode("AB1234"));
System.out.println(checkPostcode("123456"));
System.out.println(checkPostcode("ABCDEF"));
System.out.println(checkPostcode("12345A"));
System.out.println(checkPostcode("A12345"));
System.out.println(checkPostcode("A12345B"));
System.out.println(checkPostcode("1ABCDE6"));
System.out.println(checkPostcode("1ABCD6"));
}
public static boolean checkPostcode(String postCode) {
return postCode.matches("[1-9]{1}[0-9]{3}[a-zA-Z]{2}");
}
}
Output:
true
true
false
true
true
false
false
false
false
false
false
false
false
Non-regex solution:
public static boolean checkPostcode(String postCode) {
if (postCode.length() != lengthPost || postCode.charAt(0) == '0') {
return false;
}
if (postCode.length() == lengthPost) {
for (int i = 0; i < postCode.length(); i++) {
if (i < 4 && Character.isLetter(postCode.charAt(i))) {
return false;
}
if (i > 3 && Character.isDigit(postCode.charAt(i))) {
return false;
}
}
}
return true;
}
If I understand correctly, the first 4 symbols are digits, so the if condition should be
(i < 4)
because otherwise you check the first 5 symbols for a digit
While you could solve this problem with regular expressions, it is also possible to solve it along the lines you have chosen. I would write two helper methods, one to check that all characters within a given subsequence of a String are digits and another to check for letters. Like,
private static boolean allDigits(String s, int start, int end) {
for (int i = start; i < end; i++) {
if (!Character.isDigit(s.charAt(i))) {
return false;
}
}
return true;
}
private static boolean allLetters(String s, int start, int end) {
for (int i = start; i < end; i++) {
if (!Character.isLetter(s.charAt(i))) {
return false;
}
}
return true;
}
Then the checkPostcode can delegate to those two methods. Like,
public static boolean checkPostcode(String postCode) {
if (postCode != null && postCode.length() == 6) {
return allDigits(postCode, 0, 4) && allLetters(postCode, 4, 6);
}
return false;
}
And if you choose to use a regular expression compile it with a Pattern for better performance. Like,
private static Pattern POSTCODEPATTERN = Pattern.compile("\\d{4}[A-Za-z]{2}");
public static boolean checkPostcode(String postCode) {
return postCode != null && POSTCODEPATTERN.matcher(postCode).matches();
}

NZEC error for ACODE spoj

I am solving the Acode problem of SPOJ.It is a simple Dp problem here
This is my solution:
//http://www.spoj.com/problems/ACODE/
import java.util.Scanner;
//import java.util.Math;
public class Acode {
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
String encodedString = sc.next();
while (!encodedString.equals("0")) {
long number = numOfDecodings(encodedString);
System.out.println(number);
encodedString = sc.next();
}
return;
}
public static long numOfDecodings(String encodedString)
{
int lengthOfString = encodedString.length();
long decode[] = new long[lengthOfString];
decode[0] = 1;
if (isCurrentTwoDigitsValid(encodedString, 1)) {
decode[1] = 2;
} else {
decode[1] = 1;
}
for (int i=2; i<lengthOfString; i++) {
if (isCurrentTwoDigitsValid(encodedString, i)) {
decode[i] = decode[i-2] + decode[i-1];
} else {
decode[i] = decode[i-1];
}
}
return decode[lengthOfString-1];
}
public static boolean isCurrentTwoDigitsValid(String encodedString, int startIndex)
{
char c1 = encodedString.charAt(startIndex);
char c2 = encodedString.charAt(startIndex-1);
if ( (c2=='1') || (c2=='2' && c1<='6')) {
return true;
} else {
return false;
}
}
}
But I am getting an NZEC error when I try to submit it.I tested it for large values too and it is not breaking.I am not understanding how else to improve it.
When input size is 1 you get an error in
if (isCurrentTwoDigitsValid(encodedString, 1)) {
decode[1] = 2;
} else {
decode[1] = 1;
}
because of accessing out of the decode array bounds.
You treat 0 as a valid number, but it's not. For example, the correct answer for input "10" is 1, not 2.

Hangman checking used guesses form user

I am looking for some help scanning the array for the used letters in the user input and tell them, so I am lost at this point.
/**
*
*/
package Hangman;
import java.io.IOException;
/**
* #author
*
*/
public class Hangman {
static int choice;
static String solve;
static String promt;
static String guess;
static char chaGuess;
static char[] guesses = new char[25];
static char[] check;
static int counter = 1;
static boolean contine;
public static void main(String[] args) throws IOException, InterruptedException {
playerOne();
for (int i = 0; i < 300; i++) {
System.out.println(" ");
}
while (contine = true) {
playerTwo();
choiceMade(choice);
}
}
public static String playerOne() throws IOException {
System.out.println("Welcome player one");
promt = ConsoleUI.promptForInput("Enter a Phrase or word for Player Two to guess", true);
return promt;
}
public static int playerTwo() throws IOException {
String[] ask = new String[3];
ask[0] = "Give up";
ask[1] = "Guess a letter";
ask[2] = "Solve the puzle";
choice = ConsoleUI.promptForMenuSelection(ask, true);
return choice;
}
public static void choiceMade(int c) throws IOException {
if (c == 0) {
contine = false;
System.out.println("Thank you for playing");
System.exit(0);
}
if (c == 1) {
guess = ConsoleUI.promptForInput("Enter your guess", true);
guessChar(guess);
contine = true;
} else if (c == 2) {
solve = ConsoleUI.promptForInput("Enter your answer", true);
if (solve.equals(promt)) {
System.out.println("You solved it you're amazing");
contine= false;
} else {
System.out.println("Sorry you guessed it wrong.");
System.exit(0);
contine= false;
}
}
}
public static char guessChar(String g) {
chaGuess = g.charAt(0);
promt = promt.replace(" ", "");
check = promt.toCharArray();
if(guesses[counter -1] != chaGuess)
if (chaGuess >= 'a' && chaGuess <= 'z' || chaGuess >= 'A' && chaGuess <= 'Z') {
guesses[counter] = chaGuess;
System.out.println(guesses);
}
if(guesses[counter - 1] == chaGuess)
{
System.out.println("You all ready guessed that");
}
}
counter++;
return chaGuess;
}
}
Use a string, append each used guess to the end of it, and then just use indexOf()

Remove User Duplicate From Array String

I am trying to create a program that accepts as many Social Security Numbers as the user wants to input. The only restriction is that the numbers must follow the format XXX-XX-XXXX and not accept duplicated entries. This is what I have so far:
Subclass 2
package SSNServerStorageExpanded;
class SSNArray{
final String[] ssnNumber;
int arrayCount;
public SSNArray(){//defult contructor
ssnNumber = new String[9999];
arrayCount = 0;
}
public SSNArray(int arraySize){
ssnNumber = new String[arraySize];
arrayCount = 0;
}
public String[] getSSNNumber(){
return ssnNumber;
}
public int getArrayCount(){
return arrayCount;
}
public boolean validateSSNNumber(String SSNFormat){
return SSNFormat.matches("\\d{3}-\\d{2}-\\d{4}");
}
public String addSSN(String SSNFormat){
if(validateSSNNumber(SSNFormat)){
return ssnNumber[arrayCount++] = SSNFormat;
}else{
return null;
}
}
#Override
public String toString(){
String str = "\nThe Social Security Number(s) you entered is(are):\n";
for(int x = 0; x < arrayCount; x++){/
str += ssnNumber[x] + "\n";
}return str;
}
}
Subclass 1
package SSNServerStorageExpanded;
public class SSNArrayExpanded extends SSNArray{
public SSNArrayExpanded(){
super();
}
public SSNArrayExpanded(int arraySize){
super(arraySize);
}
#Override
public boolean validateSSNNumber(String SSNFormat){
if(super.validateSSNNumber(SSNFormat)){
boolean duplicate = false;
for(int y = 0; y < arrayCount; y++){
if(ssnNumber[y].equals(ssnNumber[arrayCount])){
System.out.println("No duplicates allowed, please try again");
duplicate = true;
break;
}
}
if(!duplicate){
arrayCount++;
}
}
return true;
}
}
Mainclass
package SSNServerStorageExpanded;
import java.util.Scanner;
public class SSNArrayTestExpanded{
public static void main(String[] args){
SSNArrayExpanded SSNArrayExpandedObject = new SSNArrayExpanded();
Scanner input = new Scanner(System.in);
System.out.println("Initiating SSN Server Storage Expanded");
System.out.println("► Type 'EXIT' at any moment to close the program ◄\n");
boolean run = true;
while(run){
System.out.print("Enter your Social Security Number(XXX-XX-XXXX): ");
String ssnNumber = input.next();
if(ssnNumber.equalsIgnoreCase("EXIT")){
System.out.print(SSNArrayExpandedObject.validateSSNNumber(ssnNumber));
return;
}else if(SSNArrayExpandedObject.validateSSNNumber(ssnNumber)){
SSNArrayExpandedObject.addSSN(ssnNumber);
}else{
System.out.println("!Please use the format XXX-XX-XXXX!");
}
}
}
}
What am I doing wrong with my public boolean validateSSNNumber method under Subclass 1 or are there more errors in my code that I am not aware of?
In your subclass1 can you try this. You need to compare the SSNFormat String entered by user with the array values (you were comparing array values itself). Do not increase the array count here instead do it in addSSN function as you were doing.
#Override
public boolean validateSSNNumber(String SSNFormat){
if(super.validateSSNNumber(SSNFormat)){
boolean duplicate = false;
for(int y = 0; y < arrayCount; y++){
if(ssnNumber[y].equals(SSNFormat)){
System.out.println("No duplicates allowed, please try again");
duplicate = true;
break;
}
}
if(!duplicate){
return true;
}
}
return false;
}
In the SSNArray class use this function for adding SSN number without validating the SSNFormat again.
public String addSSN(String SSNFormat){
return ssnNumber[arrayCount++] = SSNFormat;
}
You can try using a Set, which will easily help you to check for any duplicates and will reduce your iteration over array.
Why cant you go for LinkedHashSet data structure for storing the ssn number.?, provides easy retrieval and duplicate check in an order of O(1).
final LinkedHashSet<String> ssnNumber;
also the code
#Override
public boolean validateSSNNumber(String SSNFormat){
if(super.validateSSNNumber(SSNFormat)){
boolean duplicate = ssnNumber.add(SSNFormat);
if(duplicate){
System.out.println("No duplicates allowed, please try again");
return false;
}
return true;
}
return false
}
Here is your complete Solution, with this you can add N-number of SSN-Number as you want,
import java.util.HashSet;
import java.util.Scanner;
class SSNSet{
final HashSet<String> allSsnNumber = new HashSet<String>();
public HashSet<String> getAllSsnNumber() {
return allSsnNumber;
}
public boolean validateSSNNumber(String SSNFormat){
return SSNFormat.matches("\\d{3}-\\d{2}-\\d{4}");
}
public boolean addSSN(String SSNFormat){
if(validateSSNNumber(SSNFormat)){
boolean flag;
if(allSsnNumber.add(SSNFormat)){
System.out.println("Added Successfully");
flag = true;
}else{
System.out.println("Duplicate Not Allow");
flag = false;
}
return flag;
}else{
System.out.println("!Please use the format XXX-XX-XXXX!");
return false;
}
}
}
public class SSNArrayTestExpanded{
public static void main(String[] args){
SSNSet SSNArrayExpandedObject = new SSNSet();
Scanner input = new Scanner(System.in);
System.out.println("Initiating SSN Server Storage Expanded");
System.out.println(" Type 'EXIT' at any moment to close the program \n");
boolean run = true;
while(run){
System.out.print("Enter your Social Security Number(XXX-XX-XXXX): ");
String ssnNumber = input.next();
if(ssnNumber.equalsIgnoreCase("EXIT")){
break;
/*System.out.print(SSNArrayExpandedObject.validateSSNNumber(ssnNumber));
return;*/
}else{
SSNArrayExpandedObject.addSSN(ssnNumber);
}
}
System.out.println("===============================================");
System.out.println("You have entered SSN Numbers are : ");
System.out.println(SSNArrayExpandedObject.getAllSsnNumber());
System.out.println("===============================================");
System.out.println("Program Ended Successfully");
}
}
and Output is :
Initiating SSN Server Storage Expanded
Type 'EXIT' at any moment to close the program
Enter your Social Security Number(XXX-XX-XXXX): 111-11-1111
Added Successfully
Enter your Social Security Number(XXX-XX-XXXX): 222-22-222
!Please use the format XXX-XX-XXXX!
Enter your Social Security Number(XXX-XX-XXXX): 111-11-1111
Duplicate Not Allow
Enter your Social Security Number(XXX-XX-XXXX): 333-33-333
!Please use the format XXX-XX-XXXX!
Enter your Social Security Number(XXX-XX-XXXX): 333-33-3333
Added Successfully
Enter your Social Security Number(XXX-XX-XXXX): EXIT
===============================================
You have entered SSN Numbers are :
[111-11-1111, 333-33-3333]
===============================================
Program Ended Successfully
public boolean validateSSNNumber(String SSNFormat) {
if (super.validateSSNNumber(SSNFormat)) {
/*
*Hashset add() - Returns true if this set did not already contain
*the specified element.
*If this set already contains the element, the call leaves the set
* unchanged and returns
*/
boolean duplicate = !uniqueSSNNum.add(SSNFormat);
return duplicate;
}
return false;
}
//To use HastSet it's better if you override equals and hashcode
//using the fields that you'll use for comparison equality
// generated using eclipse
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + arrayCount;
result = prime * result + Arrays.hashCode(ssnNumber);
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
SSNArray other = (SSNArray) obj;
if (arrayCount != other.arrayCount)
return false;
if (!Arrays.equals(ssnNumber, other.ssnNumber))
return false;
return true;
}

Categories