I wonder if anyone could help me out here. I'm trying to do a brute-force algorithm that will follow a specific pattern.
I can make it output the pattern with some sloppy code work but this stuff is kind of new to me. I have really no idea how to go on from here. If you have an idea how I could do this, I would really apreciate it.
The pattern looks like this
AA0AA0A0
So I want it to bruteforce from AA0AA0A0 and up to AA9AA9A9 then will it go to AA0AA0B0
I would highly appreciate all suggestions. I have tried to google some solution, but not really found anything special.
Explanation of the process:
Starts with generating the first string AA0AA0A0.
Then it generates all the way up to AA0AA0A9.
Then it start with the next number so it would be AA0AA1A0.
So it will count up all the way to AA9AA9AA9 which would result it to jump to AA0AA0B0.
Also updated the code so it's working now.
private static char[] fCharList = { '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 char[] fNumList = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
static void Main(string[] args)
{
StartBruteForce(8);
}
public static void StartBruteForce(int length)
{
StringBuilder sb = new StringBuilder(length);
char currentChar = fCharList[0];
char currentNum = fNumList[0];
for (int i = 1; i <= 2; i++)
{
sb.Append(currentChar);
}
for (int i = 1; i <= 1; i++)
{
sb.Append(currentNum);
}
for (int i = 1; i <= 2; i++)
{
sb.Append(currentChar);
}
for (int i = 1; i <= 1; i++)
{
sb.Append(currentNum);
}
for (int i = 1; i <= 2; i++)
{
sb.Append(currentChar);
}
for (int i = 2; i <= 1; i++)
{
sb.Append(currentNum);
}
//Console.WriteLine(sb);
//Console.ReadLine();
ChangeCharacters(7, sb, length);
}
private static StringBuilder ChangeCharacters(int pos, StringBuilder sb, int length)
{
for (int i = 0; i <= sb.Length - 1; i++)
{
//sb.setCharAt(pos, fCharList[i]);
sb.Replace(sb[pos], fNumList[i], pos, 1);
//sb.Replace(sb[pos], fCharList[i], pos, 1);
if (pos == length - 1)
{
// Write the Brute Force generated word.
Console.WriteLine(sb.ToString());
Console.ReadLine();
}
else
{
ChangeCharacters(pos - 1, sb, length);
}
}
return sb;
}
Yet another alternative solution:
var results = from a0 in charList
from a1 in charList
from a2 in charList
from a3 in charList
from a4 in charList
from a5 in numList
from a6 in numList
from a7 in numList
select "" + a0 + a1 + a5 + a2 + a3 + a6 + a4 + a7;
Again, a nice one-statement solution thanks to LINQ.
Start by reading my article on how to compute a Cartesian product:
https://blogs.msdn.microsoft.com/ericlippert/2010/06/28/computing-a-cartesian-product-with-linq/
Now it should be clear how to proceed:
var results = from product in CartesianProduct(
new[] { charList, charList, charList, charList, charList, numList, numList, numList } )
let a = product.ToArray()
select "" + a[0] + a[1] + a[5] + a[2] + a[3] + a[6] + a[4] + a[7];
Behold the power of LINQ: solving your combinatorics problems in a single statement.
I think the easiest way to do this is to split the pattern in two; one for the digits, and one for the chars. The digits progress from 000 to 999, and the chars from AAAAA to ZZZZZ. You then just have to splice the digits into the right places of the chars.
IEnumerable<string> Strings()
{
var digits = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var chars = Enumerable.Range((int)'A', (int)'Z' - (int)'A' + 1).Select(i => (char)i).ToArray();
for (var c = 0L; c < Math.Pow(chars.Length, 5); ++c)
{
var cstr = chars[(c / (chars.Length * chars.Length * chars.Length * chars.Length) % chars.Length)].ToString()
+ chars[(c / (chars.Length * chars.Length * chars.Length) % chars.Length)]
+ chars[(c / (chars.Length * chars.Length) % chars.Length)]
+ chars[(c / (chars.Length) % chars.Length)]
+ chars[(c % chars.Length)];
for (var i = 0L; i < 999; ++i)
{
var istr = (i / 100 % 10).ToString()
+ (i / 10 % 10).ToString()
+ (i % 10).ToString();
var str = cstr.Substring(0, 2) + istr.Substring(0, 1) + cstr.Substring(2, 2) + istr.Substring(1, 1) + cstr.Substring(4, 1) + istr.Substring(2, 1);
yield return str;
}
}
}
Using it it like this:
var early = Strings().Take(15);
var late = Strings().Skip(1234).Take(15);
foreach (var s in early.Concat(late))
{
Console.WriteLine(s);
}
will print this:
AA0AA0A0
AA0AA0A1
AA0AA0A2
AA0AA0A3
AA0AA0A4
AA0AA0A5
AA0AA0A6
AA0AA0A7
AA0AA0A8
AA0AA0A9
AA0AA1A0
AA0AA1A1
AA0AA1A2
AA0AA1A3
AA0AA1A4
AA2AA3B5
AA2AA3B6
AA2AA3B7
AA2AA3B8
AA2AA3B9
AA2AA4B0
AA2AA4B1
AA2AA4B2
AA2AA4B3
AA2AA4B4
AA2AA4B5
AA2AA4B6
AA2AA4B7
AA2AA4B8
AA2AA4B9
I think it would be better if you have a function that returns the next "pattern" string, so you can have a single for loop.
Something like this:
public static string Next(string pattern)
{
bool carry = true;
var sb = new List<char>();
int t;
for(int i = pattern.Length - 1; i >= 0; i--)
{
if (!carry)
{
sb.Insert(0, pattern[i]);
continue;
}
if (char.IsDigit(pattern[i]))
{
t = int.Parse(pattern[i].ToString()) + 1;
if (t == 10)
{
sb.Insert(0, '0');
carry = true;
}
else
{
sb.Insert(0, t.ToString()[0]);
carry = false;
}
}
else
{
t = (int)pattern[i] + 1;
if (t == 91)
{
sb.Insert(0, 'A');
carry = true;
}
else
{
sb.Insert(0, Convert.ToChar(t));
carry = false;
}
}
}
return new string(sb.ToArray());
}
Check the .Net Fiddle
Some simple loops will iterate over and build a new string each time. you can convert chars to int and back. So you can treat each letter as a number. This assumes your pattern is always AA0AA0A0. If that changes you would need to make the program smarter.
static void Main(string[] args)
{
foreach (var results in BruteForce())
{
Console.WriteLine(results);
}
}
public static IEnumerable<String> BruteForce()
{
const int firstLetter = 'A';
const int lastLetter = 'Z';
for (var firstPos = firstLetter; firstPos <= lastLetter; firstPos++)
{
for (var secondPos = firstLetter; secondPos <= lastLetter; secondPos++)
{
for (var thirdPos = 0; thirdPos <= 9; thirdPos++)
{
for (var fourthPos = firstLetter; fourthPos <= lastLetter; fourthPos++)
{
for (var fifthPos = firstLetter; fifthPos <= lastLetter; fifthPos++)
{
for (var sixthPos = 0; sixthPos <= 9; sixthPos++)
{
for (var sevethPos = firstLetter; sevethPos <= lastLetter; sevethPos++)
{
for (var eighthPos = 0; eighthPos <= 9; eighthPos++)
{
yield return
String.Join(string.Empty,
(char) firstPos,
(char) secondPos,
thirdPos,
(char) fourthPos,
(char) fifthPos,
sixthPos,
(char) sevethPos,
eighthPos);
}
}
}
}
}
}
}
}
}
public static IEnumerable<String> loop()
{
char[] chars = new char[] { 'a', 'b', 'c' };
for (int i = 0; i < 3000; i++)
{
string s = string.Format("aa{0}aa{1}{2}{3}", (i % 1000) / 100, (i % 100) / 10, chars[(i % 10000) / 1000], i % 10);
System.Diagnostics.Debug.WriteLine(s);
yield s;
}
}
Alternative solution:
Make a counter that goes up from 0 to 10 * 10 * 10 * 26 * 26 * 26 * 26 * 26 - 1. It should be a long.
On each tick of the counter, let the number be c. The bottom digit is '0' + c%10. The next digit is '0' + c/10%10. The next is '0' + c/(10*10)%10. The bottom letter is 'A' + c/(10*10*10)%26. The next letter is 'A' + c/(10*10*10*26)%26. And so on.
Put the letters and digits together in the right order and yield the result.
Turning this into code is left as an exercise.
Related
I want to convert a Byte array as fast as possible to a Hex String.
So through my previous question, I found the following code:
private static readonly uint[] _lookup32 = CreateLookup32();
private static uint[] CreateLookup32()
{
var result = new uint[256];
for (int i = 0; i < 256; i++)
{
string s = i.ToString("X2");
result[i] = ((uint)s[0]) + ((uint)s[1] << 16);
}
return result;
}
private static string ByteArrayToHexViaLookup32(byte[] bytes)
{
var lookup32 = _lookup32;
var result = new char[bytes.Length * 2];
for (int i = 0; i < bytes.Length; i++)
{
var val = lookup32[bytes[i]];
result[2 * i] = (char)val;
result[2 * i + 1] = (char)(val >> 16);
}
return new string(result);
}
This works great but the Issue with it is that the output string looks like this:
output: 0F42000AAD24120024
but i need it like this: 0F 42 00 0A AD 24 12 00 24
As my coding knowledge is kinda meh on "cryptic" looking algorithms I don't know where and how to add code so it would add a blank space between each 2 Bytes - (Hexoutputstring + " ") to it.
I could loop trough the string and add every 2 charackters a blank space but that would hugely increase the amount of time it needs to give me a useful results as appending strings is slow.
Could someone help me with the code above? Thanks you :)
private static string ByteArrayToHexViaLookup32(byte[] bytes)
{
var lookup32 = _lookup32;
var byteCount = bytes.Length;
var result = new char[3* byteCount - 1];
for (int i = 0; i < byteCount; i++)
{
var val = lookup32[bytes[i]];
int index = 3 * i;
result[index] = (char)val;
result[index + 1] = (char)(val >> 16);
if (i < byteCount - 1) result[index + 2] = ' ';
}
return new string(result);
}
If performance is one of your main concerns, I would approach it something like this:
private static readonly char[] digits = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
private static string ByteArrayToHexViaLookup32(byte[] bytes)
{
char[] buffer = new char[bytes.Length * 3];
int index = 0;
for (int i = 0; i < bytes.Length; i++)
{
if (index > 0)
buffer[index++] = ' ';
buffer[index++] = digits[(bytes[i] >> 4) & 0xf];
buffer[index++] = digits[bytes[i] & 0xf];
}
return new string(buffer, 0, index);
}
The following version doesn't require any lookup array, but I'm not sure if it's as fast.
private static string ByteArrayToHexViaLookup32(byte[] bytes)
{
char[] buffer = new char[bytes.Length * 3];
int index = 0;
for (int i = 0; i < bytes.Length; i++)
{
if (index > 0)
buffer[index++] = ' ';
buffer[index++] = GetDigit((bytes[i] >> 4) & 0xf);
buffer[index++] = GetDigit(bytes[i] & 0xf);
}
return new string(buffer, 0, index);
}
private char GetDigit(int value)
{
if (value < 10)
return (char)('0' + value);
return (char)('7' + value);
}
Both versions insert a space between bytes.
private static string ByteArrayToStringHex(byte[] bytes)
{
string hexValue = BitConverter.ToString(bytes);
hexValue = hexValue.Replace("-", " ");
return hexValue;
}
I think it results the same values as which you want
I found a code to get a different output, but it could be a hint for a solution.
public string GetCode(int number)
{
int start = (int)'A' - 1;
if (number <= 26) return ((char)(number + start)).ToString();
StringBuilder str = new StringBuilder();
int nxt = number;
List<char> chars = new List<char>();
while (nxt != 0) {
int rem = nxt % 26;
if (rem == 0) rem = 26;
chars.Add((char)(rem + start));
nxt = nxt / 26;
if (rem == 26) nxt = nxt - 1;
}
for (int i = chars.Count - 1; i >= 0; i--) {
str.Append((char)(chars[i]));
}
return str.ToString();
}
The output for this method is
A
B
C
(...)
Z
AA
AB
AC
(...)
AZ
AAA
(...)
I would like to achieve slightly different output, stated in the title. What would be the most efficient solution for it?
Rather than get code for each number it is more efficient just to count. So my code is counting to 52 (a-zA-Z) and then ripple and adding one to next 52 Place (just like decimal counting where you get to 10 and then add one to next place). See code below
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
new RipleCount52(10000);
}
}
public class RipleCount52
{
//places are a number from 0 t0 51 indicating each of the 52 charaters
//the least significant place is index 0
//when printing character the order has to be reversed so most significant place gets printed first.
public List<int> places = new List<int>();
public RipleCount52(int maxNumber)
{
int count = 0;
places.Add(count);
for (int i = 0; i < maxNumber; i++)
{
string output = string.Join("",places.Reverse<int>().Select(x => (x < 26) ? (char)((int)'a' + x) : (char)((int)'A' + x - 26)));
Console.WriteLine(output);
places[0] += 1;
//riple after all 52 letter are printed
if (count++ == 51)
{
Ripple();
count = 0;
}
}
}
private void Ripple()
{
//loop until no ripple is required
for (int i = 0; i < places.Count(); i++)
{
if (places[i] == 52)
{
//all places rippled a new place needs to be added
if (i == places.Count - 1)
{
places[i] = 0;
places.Insert(0, 0);
break;
}
}
else
{
//no more ripples are required so exit
places[i] += 1;
break;
}
places[i] = 0;
}
}
}
}
Thanks in advance, I want to generate sequence from A to Z and after that 0 to 9 and after that it will move to AA, AB, AC ..... AZ, A0, A1 .... A9, BA and so on
i had tried to implement it as following
public static string GenerateSequence(List<string> inputList)
{
string identifierCode = "A";
//check if list does not contains any element
if (!inputList.Any()) return identifierCode;
//sort codes
inputList.Sort();
//get last code
var lastItem = inputList[inputList.Count - 1];
//split code
var splittedChars = lastItem.ToCharArray();
bool incrementNext = true;
for (int i = 0; i < splittedChars.Length; i++)
{
if (incrementNext)
{
var effectedNumber = splittedChars.Length - (i + 1);
if (effectedNumber >= 0)
{
var charToIncrement = splittedChars[effectedNumber];
switch (charToIncrement)
{
case 'Z':
charToIncrement = '0';
incrementNext = false;
break;
case '9':
charToIncrement = 'A';
incrementNext = true;
splittedChars[effectedNumber] = charToIncrement;
break;
default:
charToIncrement++;
incrementNext = false;
break;
}
splittedChars[effectedNumber] = charToIncrement;
}
else
{
return "A" + splittedChars;
}
}
}
return new string(splittedChars);
}
but inputList.Sort() sorts numbers before Alphabets so my code fails after Z
Pseudo code:
Base enumeration:
yield return A, B, C .... 8, 9;
Next enumeration:
for each item in base enumeration
for each item2 in base enumeration
yield return item + item2
Enumeration N:
for each item in base enumeration
for each item2 in N-1 enumeration
yield return item + item2
So how do we do this? This is the canonical example of a recursive function:
There is an easily identifiable base case: the base enumeration.
The N deep enumeration is built on the N minus one deep enumeration.
With that in mind, consider the following code:
public static IEnumerable<string> GetNthEnumeration(IEnumerable<string> baseEnumeration, int n)
{
if (baseEnumeration == null) throw new ArgumentNullException();
if (n < 0) throw new ArgumentOutOfRangeException();
if (n == 0) //base case
{
foreach (var item in baseEnumeration) { yield return item; }
}
else //build recursively
{
foreach (var pre in baseEnumeration)
{
foreach (var post in GetNthEnumeration(baseEnumeration, n - 1))
{
yield return pre + post;
}
}
}
}
A recursive approach to generate sequence required is as follows
public static string GenerateSequence(int col)
{
if (col>=1 && col <= 36)
{
string schars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
return schars[col-1].ToString();
}
int div = col / 36;
int mod = col % 36;
if (mod == 0) { mod = 36; div--; }
return GenerateSequence(div) + GenerateSequence(mod);
}
static void Main(string[] args)
{
for (int i = 1; i < 250; i++)
{
Console.WriteLine(i + "---" + GenerateSequence(i));
}
}
You have the following issue cause "a" is greater than "A" and "A" is greater than "0": see the following ascii table .However, you can use your own comparator IComparer
Moreover, you can test the following method:
public static string GetExcelColumnName(int index)
{
var alphabet = new char[]
{
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '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'
};
var name = new char[3];
var rem = index;
for (var i = 2; i >= 0; i--)
{
var tmp = rem % alphabet.Length;
var r = alphabet[tmp];
name[i] = r;
rem = (rem-tmp) / alphabet.Length;
}
return new string(name);
}
I have this C# ITF/Interleaved 2 of 5 algorithm (from a VB Azalea Software algorithm):
public static string Interleaved25(string input)
{
if (input.Length <= 0) return "";
if (input.Length % 2 != 0)
{
input = "0" + input;
}
string result = "";
//Takes pairs of numbers and convert them to chars
for (int i = 0; i <= input.Length - 1; i += 2)
{
int pair = Int32.Parse(input.Substring(i, 2));
if (pair < 90)
pair = pair + 33;
else if (pair == 90)
pair = pair + 182;
else if (pair == 91)
pair = pair + 183;
else if (pair > 91)
pair = pair + 104;
result = result + Convert.ToChar(pair);
}
//Leading and trailing chars.
return (char)171 + result + (char)172;
}
The problem is that somehow chars with value > 89 all have empty boxes as result (using the ITF font).
I know this is an old question. But here is a solution with checksum:
using System;
public class Program
{
public static void Main()
{
var bcTxt = "0000420876801";//"29902110013"; //"0000420876801";
int prod1 = 0;
int prod2 = 0;
string Txt1 = "";
string Txt2 = "";
Txt1 = bcTxt;
// Berechnen der Prüfziffer, wenn ungerade Anzahl von Zeichen
if (Txt1.Length % 2 == 1)
{
for (int i = 0; i < Txt1.Length; i++)
{
prod1 += int.Parse(Txt1.Substring(i, 1)) * 3;
if (i < Txt1.Length -1)
{
prod1 += int.Parse(Txt1.Substring(i + 1, 1));
i += 1;
}
Console.WriteLine(prod1);
}
Console.WriteLine(prod1);
prod2 = prod1 % 10;
Console.WriteLine(prod2);
if (prod2 == 0)
{
prod2 = 10;
}
prod2 = 10 - prod2;
Txt1 += (char)(prod2 + 48);
Console.WriteLine(Txt1);
}
//Ascii Zeichen zuordnen
//beim Code 2/5 werden die Zeichen paarweise zugeordnet
Txt2 = ((char)34).ToString();
string Tmp = "";
for (int i = 0; i < Txt1.Length; i++)
{
Tmp += Txt1.Substring(i, 2);
i += 1;
if (int.Parse(Tmp) > 91)
{
Txt2 += ((char)(int.Parse(Tmp) + 70)).ToString();
}
else
{
Txt2 += ((char)(int.Parse(Tmp) + 36)).ToString();
}
Tmp = "";
}
Txt2 += ((char)35).ToString();
Console.WriteLine(Txt2);
}
}
While typing this question, I got the answer all by myself.
Here is the new code:
if (pair < 90)
pair = pair + 33;
else
{
pair = pair + 71;
}
Basically, all chars between 90 and 99 needs a + 71.
same code in vb6
Public Function DevolverI2of5(ByVal cString As String) as String
Dim i As Integer
If Len(cString) Mod 2 <> 0 Then
cString = "0" & cString
End If
Dim result As String
'Takes pairs of numbers and convert them to chars
For i = 1 To Len(cString) Step 2
Dim pair As Integer
pair = Val(Mid(cString, i, 2))
If pair < 90 Then
pair = pair + 33
Else
pair = pair + 71
End If
result = result & Chr(pair)
Next i
DevolverI2of5 = Chr(171) & result & Chr(172)
I am trying to create a function that will create all permutations of a string in an incremental fashion. I would like to start at:
AAAAA
...
AAAAB
...
ACCCC
...
...
ZZZZZ
I have looked around, and can't seem to find anything of that sort. I tried to create it, but it wasn't incrementally.
Any suggestions?
The "permutation" you are describing is better known as the Cartesian product. If you have an arbitrary number of sequences that you need to form the Cartesian product of, see my answer to this question on the subject:
Generating all Possible Combinations
Normally I wouldn't help these brute force type results... but seeing how many useless result you will get out of the set I figured I'd just toss this in.
var query = from c0 in Enumerable.Range(0, 26)
from c1 in Enumerable.Range(0, 26)
from c2 in Enumerable.Range(0, 26)
from c3 in Enumerable.Range(0, 26)
from c4 in Enumerable.Range(0, 26)
select new string(
new [] {
(char)('A' + c0),
(char)('A' + c1),
(char)('A' + c2),
(char)('A' + c3),
(char)('A' + c4),
}
);
BTW... if you just want the next value you can do something like this...
public static string Increment(string input)
{
var array = input.ToCharArray();
if (array.Any(c => c < 'A' || c > 'Z'))
throw new InvalidOperationException();
for (var i = array.Length-1; i >= 0; i--)
{
array[i] = (char)(array[i] + 1);
if (array[i] > 'Z')
{
array[i] = 'A';
if (i == 0)
return 'A' + new string(array);
}
else
break;
}
return new string(array);
}
A different variant where I had the idea of using modulo arithmetic. Note that I lowered the character to {A,B,C} to test it, since going up to Z for 5 letters is a lot of strings.
public IEnumerable<char[]> AlphaCombinations(int length = 5, char startChar = 'A', char endChar = 'C')
{
int numChars = endChar - startChar + 1;
var s = new String(startChar, length).ToCharArray();
for (int it = 1; it <= Math.Pow(numChars, length); ++it)
{
yield return s;
for (int ix = 0; ix < s.Length; ++ix)
if (ix == 0 || it % Math.Pow(numChars, ix) == 0)
s[s.Length - 1 - ix] = (char)(startChar + (s[s.Length - 1 - ix] - startChar + 1) % numChars);
}
}
...
foreach (var s in AlphaCombinations(5))
{
Console.WriteLine(s);
}
Bashed out quickly - I expect this could be done better:
public static IEnumerable<string> GenerateStrings(int length = 5)
{
var buffer = new char[length];
for (int i = 0; i < length; ++i)
{
buffer[i] = 'A';
}
for(;;)
{
yield return new string(buffer);
int cursor = length;
for(;;)
{
--cursor;
if (cursor < 0)
{
yield break;
}
char c = buffer[cursor];
++c;
if (c <= 'Z')
{
buffer[cursor] = c;
break;
}
else
{
buffer[cursor] = 'A';
}
}
}
}
Here is the LINQPad friendly code and it uses lambda expression.
void Main()
{
var chars = Enumerable.Range(65, 26);
var strings = chars.SelectMany (a =>
{
return chars.SelectMany (b => chars.SelectMany (c =>
{
return chars.SelectMany (d =>
{
return chars.Select (e => {return new string(new char[] {(char)a, (char)b, (char)c, (char)d, (char)e});});
});
}));
});
strings.Dump();
}