Create a strong password in Groovy with special character - groovy

I would like to create a strong password in groovy with alphabets both small and Capital and numbers and special chars.
Following are the required special chars:
~`!##$%^&*()-_=+[{]}\|;:'",<.>/?
I am using the below code but I would also like to at least one Special Character in my password.
def pass_length = 15;
def pool = ['a'..'z','A'..'Z',0..9,'_'].flatten();
Random rand = new Random(System.currentTimeMillis());
def passChars = (0..pass_length - 1).collect { pool[rand.nextInt(pool.size())] };
def PASSWORD = passChars.join();
Currently its creating a alphanumeric password only. Any quick changes I can make to the code? Help me as I am new to use groovy.

You can pick a random special character, and put it a random position in the generated password. This will make sure there's at least one special character in the password.
Also, why not adding the special characters to your dictionary as well? In this way there are more possibilities that a special character will end up in the final string.
def pass_length = 15;
def special = ['~' ,'`', ...] // you get the idea...
def pool = ['a'..'z','A'..'Z',0..9,'_'].flatten().plus(special);
Random rand = new Random(System.currentTimeMillis());
def passChars = (0..pass_length - 1).collect { pool[rand.nextInt(pool.size)] };
def specialChar = special[rand.nextInt(special.size)]
passChars[rand.nextInt(passChars.size)] = specialChar
def PASSWORD = passChars.join();

The below code generates a random password of a specified length using the specified base alphabet and specific number of special characters from a "special characters alphabet":
def alphabet = ('a'..'z') + ('A'..'Z') + ('0'..'9')
def specials = /~`!##$%^&*()-_=+[{]}\|;:'",<.>\/?/
def random = new Random()
def r = { max -> random.nextInt(max) } // utility closure
// to test - generate 10 passwords and print them on stdout
10.times {
// generate a 15 character password with the given alphabet and specials
// set with one or two special characters randomly inserted
def password = randomPassword(r, alphabet, specials, 15, (1..2))
println password
}
def randomPassword(r, alphabet, specials, passwordLen, specialsRange) {
// generate non-specials password
def password = randomChars(r, alphabet, passwordLen)
// cointoss to determine number of specials
def nSpecials = specialsRange.from + r(specialsRange.to-specialsRange.from+1)
// insert that number of random specials picked from the specials set
nSpecials.times {
password[r(password.size())] = specials[r(specials.size())]
}
password.join()
}
def randomChars(r, alphabet, length) {
(1..length).collect { alphabet[r(alphabet.size())] }
}
and a sample run:
~> groovy solution.groovy
06HT.Q5J4OOvN}S
U1h28bRcu{o)0l2
VxhMSD#6H7Qt(vH
9Bt!G2v.LT0u4ES
r1=RyWJO6R}x2Gl
sOBimChqOY3P1#x
5A]V4iiUQXkZdXv
R1iwlkZT-Ou;BrO
HbNAF>W4NRFSYRF
evuLb~ma%fzcSuA
~>

Just sharing this here for the record. Creates passwords from length 6 to 100 (these values can be changed in the code).
//Author: Rinaldi Michael
//Last Modified: 14th Dec 2022
//Password from length 6 to 100
import java.io.*
import java.lang.*
String passwords=""
Random rnd = new Random()
int randomNumber = rnd.nextInt(100)
if(randomNumber==0 || randomNumber<6)
randomNumber+=6
String[] passwordCharacters=["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"
,"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"
,"!","#","%","^","&","*","(",")","-","+","=",".","/",">","<",";",":","|"]
for(int p=0;p<randomNumber;)
{
try
{
passwords = passwords+passwordCharacters[rnd.nextInt(passwordCharacters.size())]
p++
}
catch(Exception ex)
{
p++
}
}
return passwords

Related

Loop with no duplicate values

Description of the problem.
Choose a number between 0 and 4 (the randomly number will indicate how many values from the list will be displayed)
Get random values from list, so that they are unique and display as a result.
My code does not work, please let me know how to fix it. I will be grateful for your help.
import groovy.json.JsonOutput
import java.util.Random
Random random = new Random()
def num = ["0","1","2","3","4"]
def randomNum = random.nextInt(num.size())
def min = 0;
def max = num[randomNum];
def list = ["Toy", "Mouse", "Cup","Book","Tiger"]
while(max > min) {
def randomValue = random.nextInt(list.size())
def theValue = list[randomValue] + '"'+ "," +
max++;
}
The result that I would like to achieve is for example:
Toy","Cup (if 2 is randomly selected)
Toy","Tiger","Book" (if 3 is randomly selected)
the available number is from 0 to 4 as many as there are possible
elements to choose from 0 - Toy, 1 - Mouse 2- Cup 3- Book 4 - tiger.
First, a number, e.g. 2, is drawn and then 2 elements are selected
randomly from the list of values.
You could do something like this:
Random random = new Random()
def list = ["Toy", "Mouse", "Cup","Book","Tiger"]
// this allows zero to be selected... if that is a violation
// of the requirement, adjust this....
int numberOfElementsToSelect = random.nextInt(list.size())
def results = []
numberOfElementsToSelect.times {
results << list.remove(random.nextInt(list.size()))
}
println results
println results.join(',')
EDIT:
Works great, I have one more question what to do to exit the script
without showing any results in case the value is empty
If you want to exit the script without showing results, you could do something like this:
Random random = new Random()
def list = ["Toy", "Mouse", "Cup","Book","Tiger"]
// this allows zero to be selected... if that is a violation
// of the requirement, adjust this....
int numberOfElementsToSelect = random.nextInt(list.size())
def results = []
numberOfElementsToSelect.times {
results << list.remove(random.nextInt(list.size()))
}
if(results) {
// do what you want with the results, like...
println results.join(',')
} else {
// do something else, could be exit the script...
System.exit(-2)
}

Groovy script for streamsets to parse string of about 1500 characters

This is for streamsets, I am trying to write groovy script.
I have string of length 1500 chars. No delimiter. The pattern is first 4 characters are some code, next 4 characters are length of word followed by the word. Again it as 4 chars of some code and 4 chars of lenght of word followed by the word.
e.g.
22010005PHONE00010002IN00780004ROSE
When you decode,it will be like
2201 - code
0005 - Length of the word
PHONE - Word
0001 - code
0002 - Length of the word
IN - Word
0078 - code
0004 - Length of the word
ROSE - Word
and so on..
I need help on groovy script to create string if the code starts with 00.
Thus the final string would be INROSE.
I am trying using while loop and str:substring.
Any help is very much appreciated.
Thanks
def dtx_buf = record.value['TXN_BUFFER']
def fieldid = []
def fieldlen = []
def dtx_out = []
def i = 13
def j = 0
while (i < dtx_buf.size())
{
// values = record.value['TXN_BUFFER']
fieldid[j] = str.substring(values,j,4)
output.write(record)
}
Expected result "INROSE"
One way would be to write an Iterator that contains the rules for parsing the input:
class Tokeniser implements Iterator {
String buf
String code
String len
String word
// hasNext is true if there's still chars left in `buf`
boolean hasNext() { buf }
Object next() {
// Get the code and the remaining string
(code, buf) = token(buf)
// Get the length and the remaining string
(len, buf) = token(buf)
// Get the word (of the given length), and the remaining string
(word, buf) = token(buf, len as Integer)
// Return a map of the code and the word
[code: code, word: word]
}
// This splits the string into the first `length` chars, and the rest
private token(String input, int length = 4) {
[input.take(length), input.drop(length)]
}
}
Then, we can use this to do:
def result = new Tokeniser(buf: '22010005PHONE00010002IN00780004ROSE')
.findAll { it.code.startsWith('00') }
.word
.join()
And result is INROSE
Take 2
We can try another iterative method without an internal class, to see if that works any better in your environment:
def input = '22010005PHONE00010002IN00780004ROSE'
def pos = 0
def words = []
while (pos < input.length() - 8) {
def code = input.substring(pos, pos + 4)
def len = input.substring(pos + 4, pos + 8) as Integer
def word = input.substring(pos + 8, pos + 8 + len)
if (code.startsWith('00')) {
words << word
}
pos += 8 + len
}
def result = words.join()

Find the even number using given number

I have to find the greatest even number possible using the digits of given number
Input : 7876541
Desired output : 8776514
Can anyone help me with the logic?
How about this?
convert it into string
sort the numbers in reverse order
join them and convert it as number
def n = 7876541
def newN = (n.toString().split('').findAll{it}.sort().reverse().join()) as Integer
println newN
You can quickly try it on-line demo
EDIT: Based on the OP comments, updating the answer.
Here is what you can do -
- find the permutations of the number
- find the even number
- filter it by maximum number.
There is already found a thread for finding the permutations, so re-using it with little changes. Credits to JavaHopper.
Of course, it can be simplified by groovified.
class Permutations {
static def list = []
public static void printPermutation(char[] a, int startIndex, int endIndex) {
if (startIndex == endIndex)
list << ((new String(a)) as Integer)
else {
for (int x = startIndex; x < endIndex; x++) {
swap(a, startIndex, x)
printPermutation(a, startIndex + 1, endIndex)
swap(a, startIndex, x)
}
}
}
private static void swap(char[] a, int i, int x) {
char t = a[i]
a[i] = a[x]
a[x] = t
}
}
def n = 7876541
def cArray = n.toString().toCharArray()
Permutations.printPermutation(cArray, 0, cArray.size())
println Permutations.list.findAll { it.mod(2) == 0}?.max()
Quickly try online demo
There is no need to create permutations.
Try this solution:
convert the source number into a string.
split the string into an array,
sort the numbers, for the time being, in ascending order,
find the index of the first even digit,
remove this number from the array (storing it in a variable),
reverse the array and add the removed number,
join the digits from the array and convert them into integer.
So the whole script looks like below:
def inp = 7876541
def chars1 = inp.toString().split('')
// findAll{it} drops an empty starting element from the split result
def chars2 = chars1.findAll{it}.sort()
// Find index of the 1st even digit
def n = chars2.findIndexOf{it.toInteger() % 2 == 0}
def dig = chars2[n] // Store this digit
chars2.remove(n) // Remove from the array
def chars3 = chars2.reverse() // Descending order
chars3.add(dig) // Add the temporarily deleted number
def out = (chars3.join()) as Integer // result
println out

Algorithm to delete duplicate characters from a String

Let us a have a string "abbashbhqa". We have to remove the duplicate characters in such a manner that the output should be "abshq". One possible solution is to check each character with the others present in the string and then manipulate. But this requires O(n^2) time complexity. Is there any optimised approach to do so ?
O(n):
Define an array L[26] of booleans. Set all to FALSE.
Construct a new empty string
Walk over the string and for each letter check if L [x] is FALSE. If so, append x to the new string and set L [x] to 1.
Copy new string to the old one.
as soon as you iterate string you create a set (or hash set). in case the alphabet is limited (English letters as in your example) you just can create a 256 boolean array and use ASCII code as a key to it. Make all booleans to be false at starting point. Each iteration you check if array[] is false or true. In case it's false, the symbol is not a duplicate, so you mark it into array[] = true, do not remove from the string and go on. in case it's true - the symbol is a duplicate
Probably this will be the implementation of the above problem
import java.util.*;
import java.io.*;
public class String_Duplicate_Removal
{
public static String duplicate_removal(String s)
{
if(s.length()<2)
return s;
else if(s.length()==2)
{
if(s.charAt(0)==s.charAt(1))
s = Character.toString(s.charAt(0));
return s;
}
boolean [] arr = new boolean[26];
for(int i=0;i<s.length();i++)
{
if(arr[s.charAt(i)-'a']==false)
arr[s.charAt(i)-'a']=true;
else
{
s= ((new StringBuilder(s)).deleteCharAt(i)).toString();
i--;
}
}
return s;
}
public static void main(String [] args)
{
String s = "abbashbhqa";
System.out.println(duplicate_removal(s));
}
}
I am solving using Python and it works in O(n) time and O(n) space --
I am using set() as set does not allow duplicates ---
In this case the order of elements gets changed --
If u want the order to remain same then u can use OrderedDict() and it also works in O(n) time --
def remove_duplicates(s , ans_set):
for i in s: # O(n)
ans_set.add(i) # O(1)
ans = ''
for char in ans_set:
ans += char
print ans
s = raw_input()
ans_set = set()
remove_duplicates(s , ans_set)
from collections import OrderedDict
def remove_duplicates_maintain_order(a):
ans_dict = OrderedDict()
for i in a: # O(n)
ans_dict[i] = ans_dict.get(i , 0) + 1 # O(1)
ans = ''
for char in ans_dict:
ans += char
print ans
s = raw_input()
remove_duplicates_maintain_order(s)

D: how to remove last char in string?

I need to remove last char in string in my case it's comma (","):
foreach(line; fcontent.splitLines)
{
string row = line.split.map!(a=>format("'%s', ", a)).join;
writeln(row.chop.chop);
}
I have found only one way - to call chop two times. First remove \r\n and second remove last char.
Is there any better ways?
import std.array;
if (!row.empty)
row.popBack();
As it usually happens with string processing, it depends on how much Unicode do you care about.
If you only work with ASCII it is very simple:
import std.encoding;
// no "nice" ASCII literals, D really encourages Unicode
auto str1 = cast(AsciiString) "abcde";
str1 = str1[0 .. $-1]; // get slice of everything but last byte
auto str2 = cast(AsciiString) "abcde\n\r";
str2 = str2[0 .. $-3]; // same principle
In "last char" actually means unicode code point (http://unicode.org/glossary/#code_point) it gets a bit more complicated. Easy way is to just rely on D automatic decoding and algorithms:
import std.range, std.stdio;
auto range = "кириллица".retro.drop(1).retro();
writeln(range);
Here retro (http://dlang.org/phobos/std_range.html#.retro) is a lazy reverse iteration function. It takes any range (unicode string is a valid range) and returns wrapper that is capable of iterating it backwards.
drop (http://dlang.org/phobos/std_range.html#.drop) simply pops a single range element and ignores it. Calling retro again will reverse the iteration order back to normal, but now with the last element dropped.
Reason why it is different from ASCII version is because of nature of Unicode (specifically UTF-8 which D defaults to) - it does not allow random access to any code point. You actually need to decode them all one by one to get to any desired index. Fortunately, D takes care of all decoding for you hiding it behind convenient range interface.
For those who want even more Unicode correctness, it should be possible to operate on graphemes (http://unicode.org/glossary/#grapheme):
import std.range, std.uni, std.stdio;
auto range = "abcde".byGrapheme.retro.drop(1).retro();
writeln(range);
Sadly, looks like this specific pattern is not curently supported because of bug in Phobos. I have created an issue about it : https://issues.dlang.org/show_bug.cgi?id=14394
NOTE: Updated my answer to be a bit cleaner and removed the lambda function in 'map!' as it was a little ugly.
import std.algorithm, std.stdio;
import std.string;
void main(){
string fcontent = "I am a test\nFile\nwith some,\nCommas here and\nthere,\n";
auto data = fcontent
.splitLines
.map!(a => a.replaceLast(","))
.join("\n");
writefln("%s", data);
}
auto replaceLast(string line, string toReplace){
auto o = line.lastIndexOf(toReplace);
return o >= 0 ? line[0..o] : line;
}
module main;
import std.stdio : writeln;
import std.string : lineSplitter, join;
import std.algorithm : map, splitter, each;
enum fcontent = "some text\r\nnext line\r\n";
void main()
{
fcontent.lineSplitter.map!(a=>a.splitter(' ')
.map!(b=>"'" ~ b ~ "'")
.join(", "))
.each!writeln;
}
Take a look, I use this extension method to replace any last character or sub-string, for example:
string testStr = "Happy holiday!";<br>
Console.Write(testStr.ReplaceVeryLast("holiday!", "Easter!"));
public static class StringExtensions
{
public static string ReplaceVeryLast(this string sStr, string sSearch, string sReplace = "")
{
int pos = 0;
sStr = sStr.Trim();
do
{
pos = sStr.LastIndexOf(sSearch, StringComparison.CurrentCultureIgnoreCase);
if (pos >= 0 && pos + sSearch.Length == sStr.Length)
sStr = sStr.Substring(0, pos) + sReplace;
} while (pos == (sStr.Length - sSearch.Length + 1));
return sStr;
}
}

Resources