diff --git a/src/main/java/PasswordGenerator.java b/src/main/java/PasswordGenerator.java new file mode 100644 index 0000000..2e23683 --- /dev/null +++ b/src/main/java/PasswordGenerator.java @@ -0,0 +1,119 @@ +import java.security.SecureRandom; + +public class PasswordGenerator { + + final String lowercaseCharacters = "abcdefghjkmnpqrstuvwxyz"; + final String uppercaseCharacters = "ABCDEFGHJKMNPQRSTUVWXYZ"; + final String digits = "0123456789"; + final String specialCharacters = ".!?=@#$()%^&/*_-+"; + final SecureRandom rand = new SecureRandom(); + + private int length = 12; + private boolean useUppercase = true; + private boolean useLowercase = true; + private boolean useDigits = true; + private boolean useSpecialCharacters = true; + private boolean requireEveryConfiguredCharacterType = true; + + + public String generateRandomPassword() { + StringBuilder generatedPassword = new StringBuilder(); + String characterPool = ""; + + if (isUseLowercase()) { + characterPool += lowercaseCharacters; + } + if (isUseUppercase()) { + characterPool += uppercaseCharacters; + } + if (isUseDigits()) { + characterPool += digits; + } + if (isUseSpecialCharacters()) { + characterPool += specialCharacters; + } + + for (int generatorPosition = 0; generatorPosition < getLength(); generatorPosition++) { + String customCharacterPool = characterPool; + + if (isRequireEveryConfiguredCharacterType()) { + if (generatorPosition == 0 && isUseLowercase()) { + customCharacterPool = lowercaseCharacters; + } else if (generatorPosition == 1 && isUseUppercase()) { + customCharacterPool = uppercaseCharacters; + } else if (generatorPosition == 2 && isUseDigits()) { + customCharacterPool = digits; + } else if (generatorPosition == 3 && isUseSpecialCharacters()) { + customCharacterPool = specialCharacters; + } else { + customCharacterPool = characterPool; + } + } + + generatedPassword.append(customCharacterPool.charAt(rand.nextInt(customCharacterPool.length()))); + } + + return shufflePassword(generatedPassword.toString()); + } + + public String shufflePassword(String password) { + StringBuilder shuffledPassword = new StringBuilder(); + StringBuilder passwordCopy = new StringBuilder(password); + + while (passwordCopy.length() != 0) { + int index = rand.nextInt(passwordCopy.length()); + char c = passwordCopy.charAt(index); + shuffledPassword.append(c); + passwordCopy.deleteCharAt(index); + } + return shuffledPassword.toString(); + } + + public boolean isUseUppercase() { + return useUppercase; + } + + public void setUseUppercase(boolean useUppercase) { + this.useUppercase = useUppercase; + } + + public boolean isUseLowercase() { + return useLowercase; + } + + public void setUseLowercase(boolean useLowercase) { + this.useLowercase = useLowercase; + } + + public boolean isUseDigits() { + return useDigits; + } + + public void setUseDigits(boolean useDigits) { + this.useDigits = useDigits; + } + + public boolean isUseSpecialCharacters() { + return useSpecialCharacters; + } + + public void setUseSpecialCharacters(boolean useSpecialCharacters) { + this.useSpecialCharacters = useSpecialCharacters; + } + + public boolean isRequireEveryConfiguredCharacterType() { + return requireEveryConfiguredCharacterType; + } + + public void setRequireEveryConfiguredCharacterType(boolean requireEveryConfiguredCharacterType) { + this.requireEveryConfiguredCharacterType = requireEveryConfiguredCharacterType; + } + + public int getLength() { + return length; + } + + public void setLength(int length) { + this.length = length; + } +} diff --git a/src/test/java/PasswordGeneratorTest.java b/src/test/java/PasswordGeneratorTest.java new file mode 100644 index 0000000..1e5f427 --- /dev/null +++ b/src/test/java/PasswordGeneratorTest.java @@ -0,0 +1,72 @@ +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.util.regex.Pattern; + +import static org.junit.jupiter.api.Assertions.*; + +class PasswordGeneratorTest { + + static PasswordGenerator passwordGenerator; + + @BeforeAll + static void init() { + passwordGenerator = new PasswordGenerator(); + } + + @Test + void testGeneratedPasswordLength() { + assertNotSame("", passwordGenerator.generateRandomPassword()); + assertEquals(passwordGenerator.generateRandomPassword().length(), passwordGenerator.getLength()); + + passwordGenerator.setLength(33); + assertEquals(passwordGenerator.getLength(), 33); + assertEquals(passwordGenerator.generateRandomPassword().length(), passwordGenerator.getLength()); + } + + @Test + void testPasswordLowercaseRequirement() { + passwordGenerator.setUseLowercase(false); + assertFalse(Pattern.compile("^(?=.*[a-z]).+$").matcher(passwordGenerator.generateRandomPassword()).matches()); + passwordGenerator.setUseLowercase(true); + assertTrue(Pattern.compile("^(?=.*[a-z]).+$").matcher(passwordGenerator.generateRandomPassword()).matches()); + } + + @Test + void testPasswordUppercaseRequirement() { + passwordGenerator.setUseUppercase(false); + assertFalse(Pattern.compile("^(?=.*[A-Z]).+$").matcher(passwordGenerator.generateRandomPassword()).matches()); + passwordGenerator.setUseUppercase(true); + assertTrue(Pattern.compile("^(?=.*[A-Z]).+$").matcher(passwordGenerator.generateRandomPassword()).matches()); + } + + @Test + void testPasswordDigitsRequirement() { + passwordGenerator.setUseDigits(false); + assertFalse(Pattern.compile("^(?=.*\\d).+$").matcher(passwordGenerator.generateRandomPassword()).matches()); + passwordGenerator.setUseDigits(true); + assertTrue(Pattern.compile("^(?=.*\\d).+$").matcher(passwordGenerator.generateRandomPassword()).matches()); + } + + @Test + void testPasswordSpecialCharactersRequirement() { + passwordGenerator.setUseSpecialCharacters(false); + assertFalse(Pattern.compile("^(?=.*[.!?=@#$()%^&/*_\\-+]).+$").matcher(passwordGenerator.generateRandomPassword()).matches()); + passwordGenerator.setUseSpecialCharacters(true); + assertTrue(Pattern.compile("^(?=.*[.!?=@#$()%^&/*_\\-+]).+$").matcher(passwordGenerator.generateRandomPassword()).matches()); + } + + @Test + void testPasswordForEveryRequiredCharacter() { + passwordGenerator.setRequireEveryConfiguredCharacterType(true); + PasswordValidator passwordValidator = new PasswordValidator(); + assertTrue(passwordValidator.validate(passwordGenerator.generateRandomPassword())); + } + + @Test + void testShufflePassword() { + String testInput = "ABcdefgh123"; + assertNotEquals(passwordGenerator.shufflePassword(testInput), testInput); + assertEquals(passwordGenerator.shufflePassword(testInput).length(), testInput.length()); + } +}