Applying complex code with multi-tasks to bruteforce logic - c#

I've recently made a simple bruteforcer. Everything goes properly as I've expected, but not when I try to make everything multi-tasked.
This is the current code I have:
private static void startBruteForce(int keyLength)
{
var keyChars = createCharArray(keyLength, charactersToTest[0]);
var indexOfLastChar = keyLength - 1;
createNewKey(0, keyChars, keyLength, indexOfLastChar);
}
private static char[] createCharArray(int length, char defaultChar)
{
return (from c in new char[length] select defaultChar).ToArray();
}
private static void createNewKey(int currentCharPosition, char[] keyChars, int keyLength, int indexOfLastChar)
{
var nextCharPosition = currentCharPosition + 1;
for (int i = 0; i < charactersToTestLength; i++)
{
keyChars[currentCharPosition] = charactersToTest[i];
if (currentCharPosition < indexOfLastChar)
{
createNewKey(nextCharPosition, keyChars, keyLength, indexOfLastChar);
}
else
{
computedKeys++;
Console.WriteLine(new string(keyChars));
if (new string(keyChars) == "hola")
{
if (!isMatched)
{
isMatched = true;
result = new string(keyChars);
}
}
}
if (isMatched) return;
}
}
my current code to call the bruteforcer:
var estimatedPasswordLength = 3;
while (!isMatched)
{
estimatedPasswordLength++;
startBruteForce(estimatedPasswordLength);
}
these are the chars I use to combine the password to test:
'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','1','2','3','4','5',
'6','7','8','9','0','!','$','#','#','-'
To get the password hola I must to wait most likely ~10 mins. So to reduce the minutes to wait, I'm trying to split the work like this using multiple tasks, and so maybe doing this
estimatedPasswordLength++;
startBruteForce(estimatedPasswordLength);
synchronously without checking the same password at the time...
I appreciate any suggestion - how would I do it?
EDIT:
Regarding to #Cicero suggestion, this is what I tried:
Parallel.For(0, 4, i => // what should 0 and 4 be?
{
if (isMatched) return;
Task task = Task.Factory.StartNew(() => startBruteForce(estimatedPasswordLength));
estimatedPasswordLength++;
});
but length is now disproportionate, I get writed on the console strings like:
aaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaab
aaaaaaaaaaaaaaaac
while estimatedPasswordLength would be 4. How can I get a solution to make this with a proportionate length?

Related

Random password generator outputs wrong amount of characters

I started learning C# a few days ago and thought that a random password generator would be a good starter project to do. It worked with letters only but now that I also want to include arrays of numbers and symbols it often outputs the wrong amount of characters like in this example:
Heres my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace randompassword
{
internal class Program
{
static void Main(string[] args)
{
// Variables
int pwlength;
string includeSym;
string includeNum;
// Dictionary
char[] symbols = { '?', '!', '$', '€', '%' };
char[] letters = { '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' };
int[] nums = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Console.Write("Choose your password length: ");
pwlength = Convert.ToInt32(Console.ReadLine());
Console.Write("Include numbers (Y/N): ");
includeNum = Console.ReadLine();
if (includeNum != "Y" && includeNum != "N")
{
Console.WriteLine("Invalid answer - Only answer the letter Y for Yes and N for No! ");
Console.Write("Include numbers (Y/N): ");
includeNum = Console.ReadLine();
}
Console.Write("Include symbols? (Y/N): ");
includeSym = Console.ReadLine();
if (includeSym != "Y" && includeSym != "N")
{
Console.WriteLine("Invalid answer - Only answer the letter Y for Yes and N for No! ");
Console.Write("Include symbols? (Y/N): ");
includeSym = Console.ReadLine();
}
Random rnd = new Random();
for (int z = 1; z <= pwlength; z++)
{
int rndList = rnd.Next(1, 4);
if (rndList == 1)
{
int rndChar = rnd.Next(0, 53);
Console.Write(letters[rndChar]);
}
else if (rndList == 2)
{
int rndNum = rnd.Next(0, 11);
Console.Write(nums[rndNum]);
}
else if (rndList == 3)
{
int rndSym = rnd.Next(0, 6);
Console.Write(symbols[rndSym]);
}
}
Console.ReadKey();
}
}
}
I would suggest something like this instead:
var characters = new List<char>(){ 'a', 'b', ...
Console.Write("Include numbers (Y/N): ");
var includeNum = Console.ReadLine();
if(if (includeNum.ToLower() == "y"){
characters.AddRange( new []{ '?', '!', '$', '€', '%' });
}
// Do the same for numbers
Console.Write("Choose your password length: ");
var pwlength = Convert.ToInt32(Console.ReadLine());
var password = Enumerable.Range(0, pwLength).Select(i => characters[rnd.Next(0, characters.Count)).ToString();
Console.WriteLine(password);
This should reduce the risk of any index out of bound exceptions, as well as giving a more even probability of characters.
Note that this should only be used for learning. Any proper password generator should use a secure random generator, as well ass omitting similar letters, like I/l and O/0.

Unity random characters in string

How do I repeat generating a random char? I want to make a glitched text effect so I set:
textbox.text = st[Random.Range(0, st.Length)];
in my update method. I do however only get one character out of this line - how would I repeat this process in a string with the length of 5? What I am trying to achieve is to randomly generate 5 characters over and over again. There must be a better way than this:
randomChar + randomChar + randomChar + randomChar + randomChar
Thank you in advance!
Could use something similar:
public static readonly char[] CHARS = { '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' };
static void Main(string[] args)
{
static string GenerateGlitchedString(uint wordCount,uint wordslength)
{
string glitchedString = "";
for (int i = 0; i < wordCount; i++)
{
for (int j = 0; j < wordslength; j++)
{
Random rnd = new Random();
glitchedString += CHARS[rnd.Next(CHARS.Length)];
}
glitchedString += " "; //Add spaces
}
return glitchedString;
}
string output = GenerateGlitchedString(5, 5);
Console.WriteLine(output);
}
You can use Linq to generate any number of random characters from an enumerable:
int howManyChars = 5;
var newString = String.Join("", Enumerable.Range(0, howManyChars).Select(k => st[Random.Range(0, st.Length)]));
textbox.text = newString;
If you want completely glitchy strings, go the way of Mojibake. Take a string, convert it to one encoding and then decode it differently. Most programmers end up familiar with this kind of glitch eventually. For example this code:
const string startWith = "Now is the time for all good men to come to the aid of the party";
var asBytes = Encoding.UTF8.GetBytes(startWith);
var glitched = Encoding.Unicode.GetString(asBytes);
Debug.WriteLine(glitched);
consistently results in:
潎⁷獩琠敨琠浩⁥潦⁲污潧摯洠湥琠潣敭琠桴⁥楡⁤景琠敨瀠牡祴
But, if you just want some text with some random glitches, how about something like this. It uses a set of characters that should be glitched in, a count of how many glitches there should be in a string (based on the string length) and then randomly inserts glitches:
private static Random _rand = new Random();
private const string GlitchChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!##$%&";
public static string GlitchAString(string s)
{
var glitchCount = s.Length / 5;
var buffer = s.ToCharArray();
for (var i = 0; i < glitchCount; ++i)
{
var position = _rand.Next(s.Length);
buffer[position] = GlitchChars[_rand.Next(GlitchChars.Length)];
}
var result = new string(buffer);
Debug.WriteLine(result);
return result;
}
The first two times I ran this (with that same Now is the time... string), I got:
Original String:
Now is the time for all good men to come to the aid of the party
First Two Results:
LowmiW HhZ7time for all good mea to comX to ths aid oV the p1ray
Now is fhO P!me forjall gKod men to #ome to the a#d of F5e Nawty
The algorithm is, to some extent, tunable. You can have more or fewer glitches. You can change the set of glitch chars - whatever you'd like.

How to sort an array of non-english (Slovanian) words in C#?

I have a string composes of Slovenian characters such as (žiga, špela, črt, ...) and i need to sort this string alphabetically, the problem i want to do that using loops only without using any builtin function in .NET like array.Sort().
static string[] SortByName(string[] fullname)
{
char[] abc =
{
'a', 'b', 'c', 'č', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'r', 's', 'š','t', 'u', 'v', 'z', 'ž'
};
int counter = 0;
for (int i = 0; i<abc.Length;i++)
{
for (int j = 0; j < fullname[counter].Length; j++)
{
// I still cant figure out what i can do here
}
counter++;
}
}
In your program, the char array abc stores all the Slovenian alphabets in order. You can use this array as a reference to the ranks of all the Slovene alphabets to compare the Slovene words. In the code below, I have defined a method CompareSl() to compare Slovene words, just like the Compare() method of the String class compares English words. (The method index() returns the index of a character in the array abc.)
The Compare() method of the String class takes two strings s1 and s2 as arguments and
♦ Returns 0 if the strings are equal
♦ Returns (+)ve if s1 > s2
♦ Returns (-)ve if s1 < s2
using System;
class Sl_Sort{
static void Main(){
string[] words = new string[]{"žiga", "špela", "črt"};
Console.WriteLine("Unsorted array is");
foreach(String st in words)
Console.Write(st+" , ");
//do selection sort to sort in ascending order
for(int i=0; i<words.Length-1;i++){
int min = i;
for(int j=i+1; j<words.Length;j++){
if(CompareSl(words[min], words[j]) > 0)
min = j;
}
string temp = words[i];
words[i] = words[min];
words[min] = temp;
}
Console.WriteLine("\nSorted array is");
foreach(String st in words)
Console.Write(st+" , ");
Console.ReadKey(); //waits till user presses a key before terminating
}
public static int CompareSl(string s1, string s2){
if(s1.Length == s2.Length){
for(int i=0; i<s1.Length; i++){
if(s1[i] != s2[i])
return index(s1[i]) - index(s2[i]);
}
}
else{
String s = s1.Length<s2.Length?s1:s2;
for(int i=0; i<s.Length; i++){
if(s1[i] != s2[i])
return index(s1[i]) - index(s2[i]);
}
if(s == s1)
return -1;
else
return 1;
}
return 0;
}
private static int index(char c){
char[] abc = { 'a', 'b', 'c', 'č', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'r', 's', 'š', 't', 'u', 'v', 'z', 'ž' };
for(int i=0; i<abc.Length; i++){
if(abc[i]==c)
return i;
}
return -1;
}
}
OUTPUT:
Unsorted array is
ziga , spela , crt ,
Sorted array is
crt , spela , ziga
Note: The characters ž, š and č got converted to z, s and c respectively because the platform I ran the code on was not set to UTF-8 or Unicode, which support Slovene, but ANSI, which does not support Slovene. Make sure your system supports Slovene to get the correct output.
Hope this helps.
Maybe you could do something like this:
private char[] charList = { 'a', 'b', 'c', 'č', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'r', 's', 'š', 't', 'u', 'v', 'z', 'ž' };
public string[] Sort(string inputStr)
{
string[] sortedChars = new string[inputStr.Length];
int index = 0;
for (int i = 0; i < charList.Length; i++)
{
for (int u = 0; u < inputStr.Length; u++)
{
sortedChars[index] = inputStr[u];
index++;
}
if (index == inputStr.Length)
return sortedChars;
}
return sortedChars;
}
I haven't tested the code, so not sure it works, but what it does is:
Iterate trough the chars, so it searches for "a" on each char of the inputString, if it's there it will be added to the sorted string[], then when it finishes with the first char, the next...etc.
Probably there's some error, maybe you can improve the code.

Ubbi Dubbi c# program code

Ubbi Dubbi is a program where before the first vowel in a word, the letters “ub” are inserted. On my code, it doesn't do it before the first vowel it does the second vowel. If I put "hello" the output is "hellubo", when it should be "hubello". Sorry if my english is bad, i'm still learning.
Console.Write("Enter word: ");
string word = Console.ReadLine();
var loc = word.IndexOfAny(new char[] {'a', 'e', 'i', 'o', 'u'});
int aloc = word.IndexOf('a');
int eloc = word.IndexOf('e');
int iloc = word.IndexOf('i');
int oloc = word.IndexOf('o');
int uloc = word.IndexOf('u');
if (aloc!= -1 && aloc > loc)
{
loc = aloc;
}
if (eloc!= -1 && eloc > loc)
{
loc = eloc;
}
if (iloc!= -1 && iloc > loc)
{
loc = iloc;
}
if (oloc!= -1 && oloc > loc)
{
loc = oloc;
}
if (uloc!= -1 && uloc > loc)
{
loc = uloc;
}
string word1 = word.Insert(loc, "ub");
Console.WriteLine(word1);
After calling of IndexOfAny all work is done. So you can skip most of your code. But you should insert a check, if there is any vowel at all:
Console.Write("Enter word: ");
string word = Console.ReadLine();
var loc = word.IndexOfAny(new char[] { 'a', 'e', 'i', 'o', 'u' });
string word1 = loc >= 0 ? word.Insert(loc, "ub") : word;
Console.WriteLine(word1);
In your code an 'e' is found, so loc = eloc is executed. But there also 'o' is found and loc = oloc is executed AFTER the 'e'-check. So the final value of loc is that one of oloc.
You can achieve it easily by below API.
private static string processWord(string word)
{
// Vowels array
char[] vowels = new char[] { 'a', 'e', 'i', 'o', 'u' };
//Find the index of your first vowel in your 'word'
int index = word.IndexOfAny(vowels);
//Insert 'ub' at above location
word = word.Insert(index, "ub");
//Return the word
return word;
}
or
private static string processWord(string word)
{
return word.Insert(word.IndexOfAny(new char[] { 'a', 'e', 'i', 'o', 'u' }), "ub");
}
Chose any method whichever easy for you to understand

How to simplify my implementation of a basic Caesar Shift Encryption algorithm c#?

So I have recently decided that my coding style is somewhat clunky. The trouble is I never seem to be able to get to a stage where I can figure out the way of simplifying it into less lines of more efficient code.
I was in a team coding situation the other day trying to code a word wrapping feature using TDD. When I was in the driving seat I spent most of my time with String.Split() and if statements this and if that. The guy I was coding with asked why so complex and went with the simpler recursive one liner that returned the values required and with a few conditions to boot him out of the recursive loop when he was done.
So my question is thus – Below is some code that I have written to do a Caesar Shift Encryption on a string input using only lower case alphabet and no spaces. The unit tests pass and I believe I have implemented the various conditions that may occur.
In a nut shell how would you guys simplify the code below to make it more readable and more efficient?
I appreciate the help on this, because at the end of the day I need to make my coding style less verbose and more simplistic and can’t figure out the best place to start.
Cheers
Code in C#:
public static string Encrypt(string inputString, int shiftPattern)
{
StringBuilder sb = new StringBuilder();
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' };
//y = x + 3 (mod 26)
foreach (var letter in inputString.ToLower())
{
if (!alphabet.Contains(letter))
{
return "The " + letter + " Character was not in the sample set, please ensure you only use letters";
}
var res = Array.IndexOf(alphabet, letter) + (shiftPattern % 26);
if (res >= 26)
{
res = res - alphabet.Length;
sb.Append(alphabet[res]);
}
else if (res < 0)
{
res = alphabet.Length + res;
sb.Append(alphabet[res]);
}
else
sb.Append(alphabet[res]);
}
return sb.ToString();
}
1.- Put sb.Append(alphabet[res]) only once outside the conditionals.
2.- Consider throw an exception instead of return a message... so later you can easily check that the operation works propertly. You should also consider let the character 'As Is' if It's not pressent in your alphabet definition. It will allow you deal with whitespaces, etc.
3.- Check that the last conditional are really necessary. At first view... It looks that it could be safety removed... so confirm it. We can add a Math.Abs function to avoid problems with negative numbers in ShiftPattern.
4.- In some places you use alphabet.Length, and in other places you use 26. Use always alphabet.Length.
5.-Don't check that (res >= 26), you can do directly a MOD operation.
public static string Encrypt(string inputString, int shiftPattern)
{
StringBuilder sb = new StringBuilder();
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' };
//y = x + 3 (mod 26)
foreach (var letter in inputString.ToLower())
{
if (!alphabet.Contains(letter)) //Consider throwing and exception instead
{
return "The " + letter + " Character was not in the sample set, please ensure you only use letters";
}
var res = Array.IndexOf(alphabet, letter) + (Math.Abs(shiftPattern) % alphabet.Length);
res = res % alphabet.Length
sb.Append(alphabet[res]);
}
return sb.ToString();
}
You can drop the array and everything in the for loop in one line of code.
StringBuilder sb = new StringBuilder();
foreach (var letter in inputString.ToLower())
sb.Append((char)((((letter - 'a') + shiftpattern)%26) + 'a'));
In: zombie & shift by 1
Out: apncjf
There is no need to hold the complete alphabet list.
Also, if you don't support spaces then your messages will be like roman latin, without spaces...
public static string Encrypt(string inputString, int shiftPattern)
{
StringBuilder sb = new StringBuilder();
foreach(char letter in inputString.ToLower())
{
int encryptedValue = 0;
if (letter == ' ')
{
encryptedValue = ' ';
}
else
{
encryptedValue = (((letter - 'a') + shiftPattern) % 26) + 'a';
}
sb.Append((char)encryptedValue);
}
return sb.ToString();
}
I would recommend the following,
in case or more than two conditions use Switch- Case.
Instead of char[] or any variable declaration use var if using 3.0 or above
For and Foreach loops are avoided using lambda expressions.
Make such methods static and put it in some common class that can be shared globally.
For more good practice . Follow Resharper tool from jetbrains
With some changes to the algorithm :
static 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' };
public static string Encrypt(string inputString, int shiftPattern)
{
if (inputString == null) return null;
if (shiftPattern <= 0)
{
shiftPattern = alphabet.Length + shiftPattern % alphabet.Length;
}
var chars = inputString.Select(c =>
{
var index = Array.IndexOf(alphabet, char.ToLower(c));
if (index == -1) return c;
var result = alphabet[(index + shiftPattern) % 26];
return char.IsLower(c) ? result : char.ToUpper(result);
});
return new string(chars.ToArray());
}
Manage the null string case.
Non-cypherable chars are kept as-is (debatable in a cypher...)
Just use linq instead of old style loops and builders.
Manage upper case
Shorter, while still understandable without problems.
I separated the return from the select for clarity here, in normal code if the return ... Select line didn't go over the column limit for the code base I would have combined the two.

Categories