Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -65 - java

i am trying to solve this question
https://www.hackerrank.com/challenges/pangrams
and here's my code
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Pangram {
public static String alltrim(String s)
{ String s1="";
int i,j,k=0;
for(i=0;i<s.length();i++)
{
char ch=s.charAt(i);
if(ch!=' ')
break;
}
for(j=s.length()-1;j>=0;j--)
{
char ch=s.charAt(j);
if(ch!=' ')
break;
}
for(k=i;k<j+1;k++)
s1 = s1 + s.charAt(k);
return s1;
}
public static void main(String[] args)
{
Scanner reader = new Scanner(System.in);
String input = reader.nextLine();String s,s1;
s = input.toLowerCase();
s1 = alltrim(s);
if( check(s1) )
System.out.println("pangram");
else
System.out.println("not pangram");
}
public static boolean check(String input)
{
int [] count = new int[26];
for( int i = 0; i < input.length(); i++ )
{
char ch = input.charAt(i);
count[ch-'a']++;
}
for( int cnt:count )
{
if( cnt ==0 )
return false;
}
return true;
}
}
i always get this error
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -65
at Pangram.check(Pangram.java:46)
at Pangram.main(Pangram.java:35)
i am trying to find out where the problem is but i coudn't ... can anyone help me?

Here's one way
public static void main(final String[] args) throws IOException {
Scanner reader = new Scanner(System.in);
String line = reader.nextLine();
// Verify input argument length.
final char[] allCharacters = new char[] { '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' };
final TreeSet<Character> charactersPresent = new TreeSet<Character>();
// Parse the line into letters.
final char[] letters = line.toLowerCase().toCharArray();
// Keep a set of those that are present.
for (final char letter : letters) {
charactersPresent.add(letter);
}
// Print the letters present in the alphabet but not in the input.
final StringBuilder missingLettersBuilder = new StringBuilder();
for (final char character : allCharacters) {
if (!charactersPresent.contains(character)) {
missingLettersBuilder.append(character);
}
}
if (missingLettersBuilder.length() == 0) {
System.out.println("This is a PANGRAM");
} else {
System.out.println("Not a PANGRAM because it doesn't have "+missingLettersBuilder.toString());
}
}

The problem is in
count[ch-'a']++;
where ch is 6(as you entered) and you are subtracting '6'-'1' so its generating a value by subtracting the ASCII values and give
count[-43]++;

The java.lang.ArrayIndexOutOfBoundsException: -65 happen because you subtract a(97) to a space character which is represented by 32 in the ASCII table (32-97=-65).
Which mean that the problem is in your allTrim method which does not replace all spaces as you probably expected.
If you want to replace all spaces of your string, you can use the replaceAll method of String.
Discard the s1 = alltrim(s); line and replace it by s1 = s.replaceAll(" ", "");.
Now entering the input you gave me in comments
aaabbb ab abc mnop xyyx xaxbbbxx
Won't give any exception.
As for the other exception you had (out of bound -43), it is simply because you entered
6 aaabbb ab abc mnop xyyx xaxbbbxx
6 is represented by 54 in the ASCII table, 54-97 = 43. Looking at the requirement on the link you gave us, you should only compare alphabetical letter so I suppose this is a mistake.
Note that you can easily remove all number of a String, your replace line would become :
s1 = s.replaceAll(" ", "").replaceAll("\\d", "");
Now it would not give any error even when entering
6 aaabbb ab abc mnop xyyx xaxbbbxx

Related

Java For Loop Ignores i Position when Letter of Array is the Same

import java.util.Scanner;
import java.lang.*;
public class testing {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
char[] engArray = {'A','B','C','D','E','F','G','H','I'};
String stringEngArray = String.valueOf(engArray);
System.out.println("Text input");
String input2 = input.nextLine().toUpperCase();
int inputedOffset = 4;
char[] finalArray = inpute2.toCharArray();
for (int i = 0; i < inputedText.length(); i++) {
int arrayPosition = inpute2.indexOf(inputedText.charAt(i));
int engPosition = stringEngArray.indexOf(inputedText.charAt(i));
int test = (arrayPosition % inputedOffset);
int newTest = engPosition+test;
finalArray[i] = engArray[newTest];
}
String output = new String(finalArray);
System.out.println(output);
}
}
I am trying to change the inputted by user text in order to accomplish some basic encryption.
When i enter abcd or tesla or world the output works as expected and is changing to aceg to tfuoa to wptod
The problem occurs when i am entering aaaa or aabbcc or generally when a letter is repeated on the text. At the second time the for loop finds the same letter it just uses the array position of the 1st read similar letter.
Any idea?
This happens because inputedText.indexOf(inputedText.charAt(i));, this is what's causing it to return the same index, since it will just grab the first occurance of a which will be the same for every a character.
You're trying to get the array position, but why are you doing it this way when the arrayposition is already the variable i?
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
char[] engArray = { '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' };
String stringEngArray = String.valueOf(engArray);
System.out.println("Text input");
String inputedText = input.nextLine().toUpperCase();
int inputedOffset = 4;
char[] finalArray = inputedText.toCharArray();
for (int i = 0; i < inputedText.length(); i++) {
int engPosition = stringEngArray.indexOf(inputedText.charAt(i));
int test = (i % inputedOffset);
int newTest = engPosition + test;
finalArray[i] = engArray[newTest];
}
String output = new String(finalArray);
System.out.println(output);
}
You are using indexOf() to get the arrayposition. This will always return the position of the first occurrence of that character in the string.
You can simply use i as the arrayposition.

Keypad Combinations Phone number [duplicate]

This question already has answers here:
Java recursion phone number letters
(5 answers)
Closed 7 years ago.
I know this question has been asked a hundred times but I am looking for a solution that does not involve any String functions or external classes.
I have written a few classes that actually work but they all use String.substring or String.replace, Arraylists etc. which is not allowed in my situation.
I have been on this for more than a week now and I can't seem to get any progress.
I just can't put String methods in a very big loop or something.
Any ideas?
Here is what I have written up until now.
public class Oldie {
public static void main(String[] args) {
char[][] array = {
{ '0' }, { '1' }, { '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' }
};
String num = "222";
int[] number = new int[num.length()];
char[] permutations = new char[num.length()];
for (int i = 0; i < num.length(); i++) {
number[i] = Character.getNumericValue(num.charAt(i));
}
char First, Second, Third;
for (char i = array[number[0]][0]; i <= array[number[0]][array[number[0]].length - 1]; i++) {
First = i;
for (char j = array[number[1]][0]; j <= array[number[1]][array[number[1]].length - 1]; j++) {
Second = j;
for (char k = array[number[2]][0]; k <= array[number[2]][array[number[2]].length - 1]; k++) {
Third = k;
System.out.println("" + First + "" + Second + "" + Third);
}
}
}
}
}
It would be better if I could do it in a base type solution with redix etc.
I am not quite sure, what you mean with your loops, but when you fix it, this should be another solution without saving the String (right now this throws an "java.lang.ArrayIndexOutOfBoundsException" since i dont right understand, what you want to accomplish with your for-loops). This code should be more considered as an hint how to solve your problem and not the full solution! This also kind of saves old Strings. Instead you could also delete the last char of the String at the end of each for-loop:
public class Oldie {
char[][] array = {
{ '0' }, { '1' }, { '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' }
};
String num = "222";
String savedPerm;
int[] number = new int[num.length()];
public static void main(String[] args) {
Oldie oldie = new Oldie();
oldie.givePerm(0);
}
Oldie(){
for (int i = 0; i < num.length(); i++) {
number[i] = Character.getNumericValue(num.charAt(i));
}
}
private void givePerm(int position){
String oldSavedPerm=savedPerm;
// if(array.length!=number.length){
// System.out.println("Different length!");
// System.out.println(array.length+";"+number.length);
// return;
// }
for (char c = array[number[position]][0]; c <= array[number[position]][array[number[position]].length - 1]; c++) {
savedPerm=c+oldSavedPerm;
if(position<array.length-1)
givePerm(position+1);
else
System.out.println(savedPerm);
}
}
}
Here is my approach on your problem.
char[][] array = {
{ '0' }, { '1' }, { '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' }
};
String num = "123";
// creates an combination Array
// for 123 this is {{1},{ABC},{DEF}}
char[][] combinationArr = new char[num.length()][];
for(int ix = 0; ix < num.length(); ix++)
combinationArr[ix] = array[Character.getNumericValue(num.charAt(ix))];
// now print all permutations of combination Array
// ics holds the actual index at each position
int[] ics = new int[num.length()];
boolean end = false;
while(!end){ // while there are combinations left
// print the actual combination
for(int i = 0; i < combinationArr.length; i++)
System.out.print(combinationArr[i][ics[i]]);
System.out.println();
// increases one index, starting with the last one.
// If there is no char left it starts again at 0
// and the index before will get increased.
// If the first one could not get increased
// we have all combinations.
for(int i = ics.length - 1; i >= 0; i--){
ics[i]++;
if(ics[i] == combinationArr[i].length)
if(i == 0) end = true;
else ics[i] = 0;
else break;
}
}
Here is what actually worked for me!! Thanks to ctst!
public class Oldie {
private static char[][] array = { { '0' }, { '1' }, { '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' } };
private static String num = "2222";
private static char[] savedPerm = new char[num.length];
private static int[] number = new int[num.length()];
public static void main(String[] args) {
for (int i = 0; i < num.length(); i++) {
number[i] = Character.getNumericValue(num.charAt(i));
}
givePerm(0);
}
private static void givePerm(int position) {
for (char c = array[number[position]][0]; c <= array[number[position]][array[number[position]].length - 1]; c++) {
savedPerm[position] = c;
if (position < number.length - 1)
givePerm(position + 1);
else{
for(char text: savedPerm){
System.out.print(""+text);
}
System.out.println();
}
}
}
}
I would suggest you to make a recursive method:
private String givePerm(String givenPerm, char[][] array, int position, int[] number){
if(array.length!=number.length)
return null;
for (char c = array[number[position]][0]; c <= array[number[position]][array[number[position]].length - 1]; c++) {
String permString;
if(position<array.length-1)
permString = givePerm(c+givenPerm, array, position+1);
else
permString = ""+c;
return permString;
}
}
Using recursion, you can call the permutations method and keep on reducing the the number of input digits, by grabbing the head digit and passing the tail into the next call.
public class Oldie {
private static final char[][] KEYS = {
{ '0' },
{ '1' }, { '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' }
};
public static void main(String[] args) {
try {
permutations("222");
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
public static void permutations(String inputNumber) throws IllegalArgumentException {
permutations(toDigitArray(inputNumber), "");
}
private static void permutations(int[] inputDigits, String outputLetters) throws IllegalArgumentException {
int headDigit = inputDigits[0];
int[] tailDigits = tail(inputDigits);
char[] letters = KEYS[headDigit];
for (int i = 0; i < letters.length; i++) {
char letter = letters[i];
String result = outputLetters + letter;
if (tailDigits.length == 0) {
System.out.println(result);
} else {
permutations(tailDigits, result);
}
}
}
private static int[] toDigitArray(String str) throws IllegalArgumentException {
return toDigitArray(str.toCharArray());
}
private static int[] toDigitArray(char[] arr) throws IllegalArgumentException {
int[] intArr = new int[arr.length];
for (int i = 0; i < intArr.length; i++) {
if (!Character.isDigit(arr[i])) {
throw new IllegalArgumentException("Character is not a valid digit");
}
intArr[i] = Character.digit(arr[i], 10);
}
return intArr;
}
private static int[] tail(int[] arr) {
int[] dest = new int[arr.length - 1];
System.arraycopy(arr, 1, dest, 0, dest.length);
return dest;
}
}
Output
AAA
AAB
AAC
ABA
ABB
ABC
ACA
ACB
ACC
BAA
BAB
BAC
BBA
BBB
BBC
BCA
BCB
BCC
CAA
CAB
CAC
CBA
CBB
CBC
CCA
CCB
CCC

Generate a Secure Random Password in Java with Minimum Special Character Requirements

How do I create a random password that meets the system's length and character set requirements in Java?
I have to create a random password that is 10-14 characters long and has at least one uppercase, one lowercase, and one special character. Unfortunately, some special characters are too special and cannot be used, so I cannot use just printed ASCII.
Many of the examples on this site generate a random password or session key without enough entropy in the characters or without realistic requirements in a business setting like the ones given above, so I'm asking more pointed question to get a better answer.
My character set, every special character on a standard US keyboard except for a space:
A-Z
a-z
0-9
~`!##$%^&*()-_=+[{]}\|;:'",<.>/?
I suggest using apache commons RandomStringUtils. Use something what is already done.
String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~`!##$%^&*()-_=+[{]}\\|;:\'\",<.>/?";
String pwd = RandomStringUtils.random( 15, characters );
System.out.println( pwd );
If you are using maven
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
otherwise download jar
UPDATE
Version with secure random. So matter of required characters left and can be solved as in comment, generate required parts separately and normal ones. Then join them randomly.
char[] possibleCharacters = (new String("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~`!##$%^&*()-_=+[{]}\\|;:\'\",<.>/?")).toCharArray();
String randomStr = RandomStringUtils.random( randomStrLength, 0, possibleCharacters.length-1, false, false, possibleCharacters, new SecureRandom() );
System.out.println( randomStr );
I recently learned about Passay. It provides the required functionality needed in its PasswordGenerator class. It randomly generates passwords meeting the requirements similar to what is written below using CharacterRules rather than PasswordCharacterSets as I have done below. Instead of holding a list of unused indexes for random character insertion, it simply shuffles the character buffer after inserting characters that meet the requirements.
Below is left over from before, I recommend using Passay if your licensing allows it, this code should work otherwise and provides details of why the generated passwords are crytographically strong
I ended up writing this code twice. Once to get a random character result, but it turned out the distribution of characters depended on the size of the character set(whoops!). I rewrote it and now you should just copy/paste the code and change the Main.java to the character sets you want. Although it could have been done differently, I think this is a relatively straightforward approach to get the correct result and I encourage reuse, comments, criticisms, and well-thought edits.
The controls of the PasswordGenerator code is as follows:
Min/Max Length: Set using a random number
PasswordCharacterSet: It is assumed that all PasswordCharacterSets passed into PasswordGenerator consist of unique character sets, if not, the random characters will have a skew towards the duplicates.
PasswordCharacterSet Min Characters: The min characters to use for this character set.
The main bits for the actual password generation:
Randomness of Random: We're using SecureRandom which is backed by a cryptographically strong PRNG, rather than the Random class which is not.
Random character order for the password: All the indexes of the pw char array are added to the remainingIndexes array. As we call addRandomCharacters, it removes an index randomly and we use the removed index to populate the array.
Random characters: In addRandomCharacters, a random index from the character index we're using is chosen and added to the pw array.
Guaranteeing minimum characters of each type are set: We simply carve out the minimum character amount first. We choose the minimum amount of random values from each character set and then move on.
Random distribution for the remaining characters: After the minimum values have been set, we want to make the rest of the characters random across all character sets. All the characters are added to a single array. The remaining slots are filled using the same strategy for the previous character sets.
Description of password complexity: Password complexity is usually talked about in bits of entropy. Here are the number of possibilities for your keyspace:
There is at least one uppercase alpha character (out of 26), one lowercase alpha character(out of 26), one digit (out of 10), and one special character (out of 32), the way you calculate the number of possibilities is the number of possibilities for each character multiplied by the number of characters since they are randomly placed in the string. So we know the possibilities for four of the characters are:
Required Characters = 26*26*10*32=216,320
All remaining characters have 94 (26+26+10+32) possibilities each
Our calculation is:
Characters Possibilities Bits of Entropy
10 chars 216,320*94^6 = 149,232,631,038,033,920 ~2^57
11 chars 216,320*94^7 = 14,027,867,317,575,188,480 ~2^63
12 chars 216,320*94^8 = 1,318,619,527,852,067,717,120 ~2^70
13 chars 216,320*94^9 = 123,950,235,618,094,365,409,280 ~2^76
14 chars 216,320*94^10 = 11,651,322,148,100,870,348,472,320 ~2^83
With this is mind, if you want the most secure passwords, you should always choose the highest amount of characters possible which is 14 in this case.
Main.java
package org.redtown.pw;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Set;
import org.redtown.pw.PasswordGenerator.PasswordCharacterSet;
public class Main {
public static void main(String[] args) {
Set<PasswordCharacterSet> values = new HashSet<PasswordCharacterSet>(EnumSet.allOf(SummerCharacterSets.class));
PasswordGenerator pwGenerator = new PasswordGenerator(values, 10, 14);
for(int i=0; i < 10; ++i) {
System.out.println(pwGenerator.generatePassword());
}
}
private static final char[] ALPHA_UPPER_CHARACTERS = { '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' };
private static final char[] ALPHA_LOWER_CHARACTERS = { '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' };
private static final char[] NUMERIC_CHARACTERS = { '0', '1', '2', '3', '4',
'5', '6', '7', '8', '9' };
private static final char[] SPECIAL_CHARACTERS = { '~', '`', '!', '#', '#',
'$', '%', '^', '&', '*', '(', ')', '-', '_', '=', '+', '[', '{',
']', '}', '\\', '|', ';', ':', '\'', '"', ',', '<', '.', '>', '/',
'?' };
private enum SummerCharacterSets implements PasswordCharacterSet {
ALPHA_UPPER(ALPHA_UPPER_CHARACTERS, 1),
ALPHA_LOWER(ALPHA_LOWER_CHARACTERS, 1),
NUMERIC(NUMERIC_CHARACTERS, 1),
SPECIAL(SPECIAL_CHARACTERS, 1);
private final char[] chars;
private final int minUsage;
private SummerCharacterSets(char[] chars, int minUsage) {
this.chars = chars;
this.minUsage = minUsage;
}
#Override
public char[] getCharacters() {
return chars;
}
#Override
public int getMinCharacters() {
return minUsage;
}
}
}
PasswordGenerator.java
package org.redtown.pw;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Random;
public class PasswordGenerator {
private final List<PasswordCharacterSet> pwSets;
private final char[] allCharacters;
private final int minLength;
private final int maxLength;
private final int presetCharacterCount;
public PasswordGenerator(Collection<PasswordCharacterSet> origPwSets, int minLength, int maxLength) {
this.minLength = minLength;
this.maxLength = maxLength;
// Make a copy of the character arrays and min-values so they cannot be changed after initialization
int pwCharacters = 0;
int preallocatedCharacters = 0;
List<PasswordCharacterSet> pwSets = new ArrayList<PasswordCharacterSet>(origPwSets.size());
for(PasswordCharacterSet origpwSet : origPwSets) {
PasswordCharacterSet newPwSet = new PwSet(origpwSet);
pwSets.add(newPwSet);
pwCharacters += newPwSet.getCharacters().length;
preallocatedCharacters += newPwSet.getMinCharacters();
}
this.presetCharacterCount = preallocatedCharacters;
this.pwSets = Collections.unmodifiableList(pwSets);
if (minLength < presetCharacterCount) {
throw new IllegalArgumentException("Combined minimum lengths "
+ presetCharacterCount
+ " are greater than the minLength of " + minLength);
}
// Copy all characters into single array so we can evenly access all members when accessing this array
char[] allChars = new char[pwCharacters];
int currentIndex = 0;
for(PasswordCharacterSet pwSet : pwSets) {
char[] chars = pwSet.getCharacters();
System.arraycopy(chars, 0, allChars, currentIndex, chars.length);
currentIndex += chars.length;
}
this.allCharacters = allChars;
}
public char[] generatePassword() {
SecureRandom rand = new SecureRandom();
// Set pw length to minLength <= pwLength <= maxLength
int pwLength = minLength + rand.nextInt(maxLength - minLength + 1);
int randomCharacterCount = pwLength - presetCharacterCount;
// Place each index in an array then remove them randomly to assign positions in the pw array
List<Integer> remainingIndexes = new ArrayList<Integer>(pwLength);
for(int i=0; i < pwLength; ++i) {
remainingIndexes.add(i);
}
// Fill pw array
char[] pw = new char[pwLength];
for(PasswordCharacterSet pwSet : pwSets) {
addRandomCharacters(pw, pwSet.getCharacters(), pwSet.getMinCharacters(), remainingIndexes, rand);
}
addRandomCharacters(pw, allCharacters, randomCharacterCount, remainingIndexes, rand);
return pw;
}
private static void addRandomCharacters(char[] pw, char[] characterSet,
int numCharacters, List<Integer> remainingIndexes, Random rand) {
for(int i=0; i < numCharacters; ++i) {
// Get and remove random index from the remaining indexes
int pwIndex = remainingIndexes.remove(rand.nextInt(remainingIndexes.size()));
// Set random character from character index to pwIndex
int randCharIndex = rand.nextInt(characterSet.length);
pw[pwIndex] = characterSet[randCharIndex];
}
}
public static interface PasswordCharacterSet {
char[] getCharacters();
int getMinCharacters();
}
/**
* Defensive copy of a passed-in PasswordCharacterSet
*/
private static final class PwSet implements PasswordCharacterSet {
private final char[] chars;
private final int minChars;
public PwSet(PasswordCharacterSet pwSet) {
this.minChars = pwSet.getMinCharacters();
char[] pwSetChars = pwSet.getCharacters();
// Defensive copy
this.chars = Arrays.copyOf(pwSetChars, pwSetChars.length);
}
#Override
public char[] getCharacters() {
return chars;
}
#Override
public int getMinCharacters() {
return minChars;
}
}
}
Here is a utility that uses just vanilla Java and implements the requirements. It basically gets one of each of the required character sets. Then populates the rest with random chars from the whole set. Then shuffles it all up.
public class PasswordUtils {
static char[] SYMBOLS = "^$*.[]{}()?-\"!##%&/\\,><':;|_~`".toCharArray();
static char[] LOWERCASE = "abcdefghijklmnopqrstuvwxyz".toCharArray();
static char[] UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
static char[] NUMBERS = "0123456789".toCharArray();
static char[] ALL_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789^$*.[]{}()?-\"!##%&/\\,><':;|_~`".toCharArray();
static Random rand = new SecureRandom();
public static String getPassword(int length) {
assert length >= 4;
char[] password = new char[length];
//get the requirements out of the way
password[0] = LOWERCASE[rand.nextInt(LOWERCASE.length)];
password[1] = UPPERCASE[rand.nextInt(UPPERCASE.length)];
password[2] = NUMBERS[rand.nextInt(NUMBERS.length)];
password[3] = SYMBOLS[rand.nextInt(SYMBOLS.length)];
//populate rest of the password with random chars
for (int i = 4; i < length; i++) {
password[i] = ALL_CHARS[rand.nextInt(ALL_CHARS.length)];
}
//shuffle it up
for (int i = 0; i < password.length; i++) {
int randomPosition = rand.nextInt(password.length);
char temp = password[i];
password[i] = password[randomPosition];
password[randomPosition] = temp;
}
return new String(password);
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
System.out.println(getPassword(8));
}
}
}
Using the random functionality of java.util package of rt.jar, we can create a random password of any length. below is the snippet for the same.
public class GeneratePassword {
public static void main(String[] args)
{
int length = 10;
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);
}
}
I know it is an old question, but maybe my solution will help someone with the same problem.
I'm using RandomStringUtils for password generator and then I check did password fulfilled conditions (at least one symbol, one capital letter, one small letter and one number and 8 characters long) with regex and if it didn't then I call again password generator with recursion until condition is not fulfilled. I can say that method is not gonna be called more than 3 times for sure!
public String generatePassword() {
String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789#!#$%&";
String password = RandomStringUtils.random( 8, characters );
String regex = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[#!#$%&])(?=\\S+$).{8,}$";
Pattern pattern = Pattern.compile( regex );
Matcher matcher = pattern.matcher( password );
if (matcher.matches()) {
return password;
} else {
return generatePassword(); // recursion
}
}
Maven dependency:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.11</version>
</dependency>
public static final Character[] ALPHA_UPPER_CHARACTERS = {'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'};
public static final Character[] ALPHA_LOWER_CHARACTERS = {'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'};
public static final Character[] NUMERIC_CHARACTERS = {'0', '1', '2', '3', '4',
'5', '6', '7', '8', '9'};
public static final Character[] SPECIAL_CHARACTERS = {'#', '#',
'$', '%', '^', '&', '*', '|', ';', ':', '?'};
**Note: I copied char set from #summer**
final List<Character[]> charSets = new ArrayList<>();
charSets.add(Constant.ALPHA_UPPER_CHARACTERS);
charSets.add(Constant.ALPHA_LOWER_CHARACTERS);
charSets.add(Constant.NUMERIC_CHARACTERS);
charSets.add(Constant.SPECIAL_CHARACTERS);
public String getFilterPassword() {
StringBuilder passBuilder = new StringBuilder();
final int charSetLen = charSets.size();
for (int i = 0; i < 10; i++) {
int randomLength = new Random().nextInt(charSetLen - 1);
Character[] newAlpha = charSets.get(randomLength);
int randomSetLen = newAlpha.length;
int randomAlphaLen = new Random().nextInt(randomSetLen - 1);
passBuilder.append(newAlpha[randomAlphaLen]);
}
return passBuilder.toString();
}

MorseCode class not translating

This program is supposed to translate English into morse code, but every time i input a word I get English letters and numbers such as "\cf0" for hi. I am pretty sure the morse code array has the right values. Could it be a formatting problem? PLease help. thanks.
MorseCode class
public class MorseCode {
public static String decode(char[] alphabet, String[] morseCode, String originalMessage) {
char currentChar;
String getMorseChar;
String convertedString = " ";
for (int i = 0; i < originalMessage.length(); i++) {
convertedString = " ";
currentChar = originalMessage.charAt(i);
getMorseChar = convert(currentChar, alphabet, morseCode);
convertedString = convertedString + getMorseChar;
}
return convertedString;
}
public static String convert (char currentChar, char[] alphabet, String[] morseCode) {
String morse = "";
for (int x = 0; x < alphabet.length; x++) {
if (currentChar == alphabet[x])
morse = morseCode[x];
}
return morse;
}
}
MorseCodeTester class
public class MorseCodeTester {
public static void main(String[] args) throws IOException {
String[] morseCode = new String[26];
char[] alphabet = { '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' };
Scanner scanner = new Scanner(System.in);
Scanner inFile = new Scanner(new File("morse.rtf"));
for (int x = 0; x < 26; x++) {
morseCode[x] = inFile.next( );
}
inFile.close();
System.out.println("What message would you like to translate?");
String originalMessage = scanner.next();
String converted = MorseCode.decode(alphabet, morseCode, originalMessage);
System.out.println(converted);
}
}

How to create a substitution keyword cipher

I am trying to develop a substitution cipher that uses a keyword to create a new cipher alphabet. I am new to Java (as I'm sure you will be able to tell!) and I am finding it
hard to wrap my head around the code for what I need to do.
My understanding is as follows:
If for example, the keyword is javben, I should start by finding the index of the "j" in the plainText string array, which is 9. I then want to shift the plainText[9] into cipherText[0] and move each other element over by 1. So the first pass of this would result in:
cipherText[] = {"j","a","b","c","d","e","f","g","h","i","k","l","m","n","o","p","q","r","s","t","u","v","w","r","x","y","z"}
Then I would find the "a" and it's it's already where it should be so I'll need to account for this and not shift it -- somehow. The next character is the "v" and so the process would continue.
After shifting everything in the cipher I should end up with:
plainText []= {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","r","x","y","z"}
cipherText[]= {"j","a","v","b","e","n","c","d","f","g","h","i","k","l","m","o","p","q","r","s","t","u","w","r","x","y","z"}
As you can see, I am reasonably sure that I understand the process of which to go through, however I am really struggling wrap my head around the code required for this. Help please!
import java.util.Scanner;
import java.io.*;
/**
* This program uses a keyword for a simple substitution cipher.
*
* #author Bryan
* #version Programming Project
*/
public class Cipher
{
// The main method removes duplicate characters in a word input by the user.
public static void main(String[] args) throws IOException
{
// Creatae a new scanner object for keyboard input
Scanner keyboard = new Scanner(System.in);
// prompt the user to enter a word
System.out.println("Please enter your keyword: ");
// and get their input
String input = keyboard.nextLine();
// the keyword will be built up here
String keyword = "";
while(input.length() > 0)
{
// get the first letter
char letter = input.charAt(0);
// if the letter is not already in the output
if (keyword.indexOf(letter) == -1)
{
// add it to the end
keyword = keyword + letter;
}
// that letter is processed : discard it
input = input.substring(1);
}
//this is just to confirm the duplicate letters in the keyword are removed
System.out.println(keyword);
getFile();
}
/**
* This asks the user to specify a filename which is then
* read into the program for enciphering
*/
public static void getFile()throws IOException
{
// Creatae a new scanner object for keyboard input
Scanner keyboard = new Scanner(System.in);
// Get the file name
System.out.println("Enter the file name: ");
String filename = keyboard.nextLine();
//Open the file
File file = new File(filename);
Scanner inputFile = new Scanner(file);
// Read the lines from the file until no more are left
while (inputFile.hasNext())
{
//Read the next line
String allText = inputFile.nextLine();
// Display the text
System.out.println(allText);
}
//Close the file
inputFile.close();
}
public static void alphabet()
{
String[] plainText = {"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"};
String[] cipherText = {"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"};
}
}
This one is quite simple, just set up a function that for every letter in the key word it just takes it out of the alphabet array and then add the two arrays together with the array of letters at the beginning and the alphabet without those letters after it. E.g:
String[] cipherKeyWord(String keyWord, String[] alphabet){
ArrayList<String> finalCipher = (ArrayList) Arrays.asList(keyWord.split("(?!^)"));
//^ This splits it into a string of every word using regular expressions
ArrayList<String> newAlphabet = (ArrayList) Arrays.asList(alphabet);
newAlphabet.removeAll(finalCipher);
finalCipher.addAll(newAlphabet);
return finalCipher.toArray(new String[finalCipher.size()]);
}
package Classes;
public class SubstitutionCipherClass {
public static void main(String[] args) {
char plainText[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'r', 'x', 'y', 'z'};
char cipherText[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'r', 'x', 'y', 'z'};
String pt = "haci";
for (int a = 0; a < pt.length(); a++) {
for (int i = 0; i < plainText.length; i++) {
if(plainText[i] == (pt.charAt(a))){
System.out.println(cipherText[i]);
}
}
}
}
}
I have done substitution cipher using following code
import java.util.*;
class SubCipher
{
public static void main(String args[])
{
String plainText = ",.<>;':\"[]{}-=_+)(*&^%$#\"#!),998683,1,x3x33,10~1,1,10~2,2,20";
String strcipherText = Encrypt(plainText);
String strdecryptedText = Decrypt(strcipherText);
System.out.println("Plain Text :"+plainText);
System.out.println("Encrypted Text :"+strcipherText);
System.out.println("Decrypted Text :"+strdecryptedText);
}
private static String Encrypt(String text)
{
byte[] textBytes = text.getBytes();
for (int i = 0; i < textBytes.length; i++)
{
int currentByteValue = (int)textBytes[i];
textBytes[i] = (byte)(currentByteValue > 255 ? currentByteValue - 255 + 2 : currentByteValue + 2);
}
String strbyte=new String(textBytes);
return strbyte;
}
private static String Decrypt(String text)
{
byte[] textBytes = text.getBytes();
for (int i = 0; i < textBytes.length; i++)
{
int currentByteValue = (int)textBytes[i];
textBytes[i] = (byte)(currentByteValue < 0 ? currentByteValue + 255 - 2 : currentByteValue - 2);
}
String strbyte=new String(textBytes);
return strbyte;
}
}

Categories