Replace specifics chars by others specifics chars [closed] - c#

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
I 've an actual function which replace specific chars by others specific chars in a string.
It works fine but I find this function is ugly. How I can replace this function by a more elegant function ?
private string CorrectString(string data)
{
string retData = string.Empty;
for (int j = 0; j < data.Length; j++)
{
char myChar = data[j];
switch (myChar)
{
case 'à':
myChar = '#';
break;
case 'ç':
myChar = '\\';
break;
case '[':
myChar = '°';
break;
case '!':
myChar = '!';
break;
case 'é':
myChar = '{';
break;
case 'è':
myChar = '}';
break;
case ']':
myChar = '§';
break;
case '¦':
myChar = 'ù';
break;
case '`':
myChar = 'µ';
break;
case '#':
myChar = '£';
break;
case '#':
myChar = 'à';
break;
case '°':
myChar = '[';
break;
case '¤':
myChar = '€';
break;
case 'µ':
myChar = '`';
break;
case '~':
myChar = '"';
break;
case 'Ý':
myChar = 'Ý';
break;
case '¢':
myChar = '¢';
break;
case '£':
myChar = '#';
break;
case '§':
myChar = ']';
break;
case '¬':
myChar = '¬';
break;
case '|':
myChar = '|';
break;
case '"':
myChar = '~';
break;
case '{':
myChar = 'é';
break;
case '}':
myChar = 'è';
break;
case 'ù':
myChar = '¦';
break;
case '\\':
myChar = 'ç';
break;
}
retData = retData.Insert(j, myChar.ToString());
}
return retData;
}

Solution 1
You can simply hold your characters in two strings:
var toTranslate = "àç[!é...";
var translateTo = #"#\°...";
and then translate as you find the characters:
int index = toTranslate.IndexOf(myChar);
if (index > -1)
{
myChar = translateTo[index];
}
Solution 2
Another, efficient but less readable way would be to store a Dictionary<char, char> and to use it like so:
myDictionary['à'] = '#';
myDictionary['ç'] = '\\';
...
if (myDictionary.Keys.Contains(myChar))
{
myChar = myDictionary[myChar];
}

If speed is not a concern, you might want to create a Dictionary<char, char> and for each key of the dictionary, check whether it is equal to a current character. If it is, then replace it by the appropriate value. Advance one character and continue.

Or a sequence of Replace statements:
myCleanString= Regex.Replace(data, "à", #"#")
.Replace("ç", "\\")
.Replace("[", "°") ...

_MyString1 = "#\\°!"; // those you put in the partial class or public class of your program
_MyString1 = "#\\°!";
string c = _MyString1.Substring(_MyString.IndexOf("à"),1);

Related

how to assign value to string and calculate in for loop [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I'm trying to assign value to each character on a string input, calculate the total and then displaying the output on a label. here's how i tried to implement it, by using switch, however the result still shows '0'. how do I solve this error?
thanks. the code is run on on-Click event in C#
string passport = "ABC123";
char[] array;
array = passport.ToCharArray(0,6);
int total = 0;
foreach (char c in array) {
switch (passport)
{
case "A":
total += 1;
break;
case "B":
total += 2;
break;
case "C":
total += 3;
break;
case "1":
total += 1;
break;
case "2":
total += 2;
break;
case "3":
total += 3;
break;
}
}
Label1.Text = total.ToString();
Combining the Comments as answer.
string passport = "ABC123";
char[] array = passport.ToCharArray(0,6);
int total = 0;
foreach (char c in array) {
switch (c) // You're doing your switch on passport rather than c. – Loocid
{
case 'A': //Make hardcoded values a type of char(with single quote) otherwise it will not compile. case 'A': – Fabio
total += 1;
break;
case 'B':
total += 2;
break;
case 'C':
total += 3;
break;
case '1':
total += 1;
break;
case '2':
total += 2;
break;
case '3':
total += 3;
break;
}
}
Label1.Text = total.ToString();

How can this C project to change vewels to $ be translated into C#?

Not a problem as much as a curiosity. I came about this old post yesterday and started playing with it in C#. Heres the original post form 2011(How to change vowels in a string to a symbol?).
I changed some of the code along with a counter to count the total letters in the word. I am stuck on the if statement. I know this program may not have any real world purpose, but I'm trying to learn C# string manipulation.
Console.WriteLine("Enter a word.");
string userWord = Console.ReadLine();
Console.WriteLine();
Console.WriteLine("You wrote {0}", userWord);
Console.WriteLine();
userWord.ToLower();
char[] wordArray = userWord.ToArray();
for (int i = 0; i < wordArray.Length; i++)
{
string theLetter = userWord.Substring(i, 1);
theLetter = theLetter.ToLower();
if (wordArray[i] == 'a' || wordArray[i] == 'e' || wordArray[i] == 'i' || wordArray[i] == 'o' || wordArray[i] == 'u')
{
wordArray[i] = '$';
}
string rebuilt = new string(wordArray);
Console.WriteLine("Your word is now: {0}", rebuilt);
Console.WriteLine("The total number of letters in your word is {0}", userWord.Length);
}
Console.ReadLine();
I just want to change the vowels to $ or any other letter or symbol and count the digits in the word.
The first problem with the C program in the post you linked to is that it only changes the lower-case vowels to '$', not the upper-case ones. The second problem is that strings in C# are immutable, and you already worked around this by changing the word into an array, modifying that, and creating a new string from the modified array.
A method to convert all vowels to '$' might look like this:
public static string VowelsToSymbol(string input)
{
if (string.IsNullOrWhiteSpace(input)) return input;
var work = new char[input.Length];
for (int i = 0; i < work.Length; i++)
{
var c = input[i];
switch (c)
{
case 'A': case 'E': case 'I': case 'O': case 'U':
case 'a': case 'e': case 'i': case 'o': case 'u':
work[i] = '$'; break;
default:
work[i] = c; break;
}
}
return new string(work);
}
Slightly less efficient but much better at showing the intent (what is being done) instead of the mechanics (how is it done):
private static char OneVowelToSymbol(char c)
{
switch (c)
{
case 'A': case 'E': case 'I': case 'O': case 'U':
case 'a': case 'e': case 'i': case 'o': case 'u':
return '$';
default:
return c;
}
}
public static string VowelsToSymbolLinq(string input)
{
return string.IsNullOrWhiteSpace(input) ? input :
new string(input.Select(OneVowelToSymbol).ToArray());
}
If you want to allow for accented characters (or whatever else may count for a vowel in some language other than English), things get ugly quite quickly, and you may be better off using a different method (search the internet for '".NET" isvowel' to find examples).

Generate Sequential Passwords in C#

I have been trying to generate passwords sequentially in C# (aaaa, aaab, aaac, ... abcd, abce) for a hash cracker (for white-hat purposes). However, I'm not sure how to do that.
Right now I have a char array, the last element of which is being incremented by a switch:
switch (character) {
case ('0'):
character = '1';
break;
case ('1'):
character = '2';
break;
case ('2'):
character = '3';
break;
case ('3'):
character = '4';
break;
case ('4'):
character = '5';
break;
case ('5'):
character = '6';
break;
case ('6'):
character = '7';
break;
case ('7'):
character = '8';
break;
case ('8'):
character = '9';
break;
case ('9'):
character = 'a';
break;
case ('a'):
character = 'b';
break;
case ('b'):
character = 'c';
break;
case ('c'):
character = 'd';
break;
case ('d'):
character = 'e';
break;
case ('e'):
character = 'f';
break;
case ('f'):
character = 'g';
break;
case ('g'):
character = 'h';
break;
case ('h'):
character = 'i';
break;
case ('i'):
character = 'j';
break;
case ('j'):
character = 'k';
break;
case ('k'):
character = 'l';
break;
case ('l'):
character = 'm';
break;
case ('m'):
character = 'n';
break;
case ('n'):
character = 'o';
break;
case ('o'):
character = 'p';
break;
case ('p'):
character = 'q';
break;
case ('q'):
character = 'r';
break;
case ('r'):
character = 's';
break;
case ('s'):
character = 't';
break;
case ('t'):
character = 'u';
break;
case ('u'):
character = 'v';
break;
case ('v'):
character = 'w';
break;
case ('w'):
character = 'x';
break;
case ('x'):
character = 'y';
break;
case ('y'):
character = 'z';
break;
case ('z'):
character = 'A';
break;
case ('A'):
character = 'B';
break;
case ('B'):
character = 'C';
break;
case ('C'):
character = 'D';
break;
case ('D'):
character = 'E';
break;
case ('E'):
character = 'F';
break;
case ('F'):
character = 'G';
break;
case ('G'):
character = 'H';
break;
case ('H'):
character = 'I';
break;
case ('I'):
character = 'J';
break;
case ('J'):
character = 'K';
break;
case ('K'):
character = 'L';
break;
case ('L'):
character = 'M';
break;
case ('M'):
character = 'N';
break;
case ('N'):
character = 'O';
break;
case ('O'):
character = 'P';
break;
case ('P'):
character = 'Q';
break;
case ('Q'):
character = 'R';
break;
case ('R'):
character = 'S';
break;
case ('S'):
character = 'T';
break;
case ('T'):
character = 'U';
break;
case ('U'):
character = 'V';
break;
case ('V'):
character = 'W';
break;
case ('W'):
character = 'X';
break;
case ('X'):
character = 'Y';
break;
case ('Y'):
character = 'Z';
break;
case ('Z'):
character = '#';
break;
case ('#'):
character = '%';
break;
case ('%'):
character = '/';
break;
case ('/'):
character = '\\';
break;
case ('\\'):
character = '\'';
break;
case ('\''):
character = '!';
break;
case ('!'):
character = '$';
break;
case ('$'):
character = '#';
break;
case ('#'):
character = '^';
break;
case ('^'):
character = '?';
break;
case ('?'):
character = ':';
break;
case (':'):
character = ',';
break;
case (','):
character = '(';
break;
case ('('):
character = ')';
break;
case (')'):
character = '[';
break;
case ('['):
character = ']';
break;
case (']'):
character = '{';
break;
case ('{'):
character = '}';
break;
case ('}'):
character = '-';
break;
case ('-'):
character = '_';
break;
case ('_'):
character = '+';
break;
case ('+'):
character = '=';
break;
case ('='):
character = '0';
break;
prev = true;
default:
character = '0';
break;
}
However, when that element reaches 0 again, I need to increment the previous digit of the password and if that digit also reaches 0, I need to increment the previous digit from that one, and so on.
Also, since this is a hash cracker, it needs to be fast. Any suggestions?
My first answer wouldn't give you quite what you want. This will:
Create a string that defines your alphabet:
const string Alphabet = "abcdefghijklmnopqrstuvwxyz0123456789";
Then initialize an int array with all -1, as long as your longest password. This one will do up to 8 characters:
int[] pwArray = new int[] {-1, -1, -1, -1, -1, -1, -1, -1};
Then run a loop:
for (int i = 0; i < Whatever; ++i)
{
string password = ToPasswordString(pwArray, Alphabet);
// do something with the password
}
string ToPasswordString(int[] pass, string alphabet)
{
for (int i = pass.Length-1; i > 0; --i)
{
pass[i]++;
if (pass[i] < alphabet.Length)
{
break;
}
pass[i] = 0;
}
var sb = new StringBuilder();
for (int i = 0; i < pass.Length; ++i)
{
if (pass[i] >= 0)
sb.Append(alphabet[pass[i]]);
}
return sb.ToString();
}
The key here is that we don't modify password characters. Rather, we modify indexes into the character array.
Granted, this won't be as fast as some other methods (passwords per second), but your program's speed is limited by how fast the site you're hacking can respond to login tries. The amount of time you spend generating passwords is irrelevant when compared to that.
Instead of a complicated and extremely large switch statement why not just directly map int values to char.
for (int i = 0; i < (int)Char.MaxValue; i++) {
char c = (char)i;
...
}
This would allow you to build up brute force password generator pretty easily.
You could use ascii code, for sample:
public char GetNextChar(char c)
{
return (char)(((int)c) + 1);
}
Would be a nice extension, for sample:
public static class Extensions
{
public static char GetNextChar(this char c)
{
return (char)(((int)c) + 1);
}
}
and using it:
character = character.GetNextChar();
Something like this should work.
char[] currPassword = new char[] { (char)65, (char)65, (char)65, (char)65, (char)65 }; //65 = A
const int Z = 90;
const int A = 65;
void Main()
{
while(true)
{
string curr = new string(currPassword);
Next();
}
}
public void Next()
{
int currIndex = currPassword.Length -1;
bool done = false;
do
{
currPassword[currIndex]++;
if(currPassword[currIndex] > Z && currIndex >= 0)
{
currPassword[currIndex] = (char)A;
currIndex--;
}
else
{
done = true;
}
}while(!done);
}
LINQLIB contains methods to compute all permutations or combinations. You could use it instead although the order might not be exactly as you describe in your question.
Another different approach:
static void Main(string[] args)
{
string charSet = "0123456789!##$%^&*";
string password = "20#";
StringBuilder start = new StringBuilder("0");
int j = 0;
int z = 0;
while (start.ToString() != password)
{
start[z] = charSet[j++];
Console.WriteLine(start);
if (j == charSet.Length)
{
if (start.ToString().Where(c => c == charSet[charSet.Length - 1]).Count() == start.ToString().Length)
{
start.Append("0");
for (int t = 0; t < start.Length; t++)
{
start[t] = '0';
}
z++;
}
else
{
for (int t = start.Length - 2; t >= 0; t--)
{
if (charSet.IndexOf(start[t]) == charSet.Length - 1)
{
start[t] = '0';
}
else
{
start[t] = charSet[charSet.IndexOf(start[t]) + 1];
break;
}
}
}
j = 0;
}
}
}
Just treat each of your password entries as numbers, its base being the number of characters present in the initial Dictionary. Whenever you reach a maximum in a given position, you 'carry over' to the next 'digit'.
This small class will return all possible combinations, given:
an initial character dictionary
a minimum password size
a maximum password size
Just keep in mind that sequences like that get EXTREMELY large very fast, depending on the initial dictionary size. For example, the following code with default values (minChar=2,MaxChar=4) generates 866495 entries.
public class Sequencer
{
public string characterDictionary = "0123456789";
//public string characterDictionary = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-=[];',./`~!##$%^&*()_+{}|:\"<>?|\\";
public int minCharCount = 2;
public int maxCharCount = 4;
private List<string> _sequence;
public List<string> GetSequence()
{
_sequence = new List<string>();
for (int i = minCharCount; i < (maxCharCount + 1); i++)
RenderCombinations(i);
return _sequence;
}
private void RenderCombinations(int charCount)
{
int _dictSize = characterDictionary.Length;
int[] _containerMatrix = new int[charCount];
char[] _splitDict = characterDictionary.ToCharArray();
bool _maxReached = false;
do
{
string _currentCombination = "";
for (int i = 0; i < charCount; i++)
_currentCombination += _splitDict[_containerMatrix[i]];
_sequence.Add(_currentCombination);
// Let the shifting begin!
bool _mustCarry = false;
int _carryIndex = 0;
do
{
_mustCarry = false;
if (_carryIndex == _containerMatrix.Length)
{
_maxReached = true;
break;
}
_containerMatrix[_carryIndex]++;
if (_containerMatrix[_carryIndex] == _dictSize)
{
_mustCarry = true;
_containerMatrix[_carryIndex] = 0;
}
_carryIndex++;
if (_carryIndex > charCount)
{
_mustCarry = false;
_maxReached = true;
}
} while (_mustCarry);
} while (!_maxReached);
}
}

Converting values with Arabic numbers

The problem states "Write a program that accepts a 10-digit telephone number that may contain one or more alphabetic characters. Display the corresponding number using numerals...etc"
ABC:2 through WXYZ:9
This chapter teaches about loops but I found myself really lost at this problem. I completed the code but I think it sucks...
My question: Is there a better way to shorten this code up? And I only figured to use the c# keyword case, is there another way?
EDIT: Arabic as in you could type in 1800WALLTO and it will give you 1800925586
ALSO I am not asking for a code that doesn't work, this does EXACTLY what I want and asked it to do. I am just asking for any advise or input on how to make it better. I really wanted to know a way to do it without switch and case break etc...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int x = 0;
char userInput = ' ';
string inputString = "",
outputString = "";
Console.WriteLine("Enter the digits from the phone number");
do
{
userInput = Console.ReadKey(false).KeyChar;
inputString += userInput;
if (Char.IsLetter(userInput))
userInput = userInput.ToString().ToUpper().ToCharArray()[0];
switch (userInput)
{
case '1':
outputString += '1';
x++;
break;
case '2':
case 'A':
case 'B':
case 'C':
outputString += '2';
x++;
break;
case '3':
case 'D':
case 'E':
case 'F':
outputString += '3';
x++;
break;
case '4':
case 'G':
case 'H':
case 'I':
outputString += '4';
x++;
break;
case '5':
case 'J':
case 'K':
case 'L':
outputString += '5';
x++;
break;
case '6':
case 'M':
case 'N':
case 'O':
outputString += '6';
x++;
break;
case '7':
case 'P':
case 'Q':
case 'R':
case 'S':
outputString += '7';
x++;
break;
case '8':
case 'T':
case 'U':
case 'V':
outputString += '8';
x++;
break;
case '9':
case 'W':
case 'X':
case 'Y':
case 'Z':
outputString += '9';
x++;
break;
case '0':
outputString += '0';
x++;
break;
default:
Console.WriteLine("You entered an incorrect value-Try again");
x--;
break;
}
}
while (x < 10);
Console.WriteLine("\nYou entered {0}", inputString);
Console.WriteLine("Your number is {0}", outputString);
}
}
}
Use a System.Collections.Generic.Dictionary where the dictionary keys are the characters A-Z and 0-9 and the values are the corresponding numbers:
var lookup = Dictionary<char, int> {
{'A',2},
{'B',2},
// etc...
{'Z', 9},
{'1':1},
{'2':2}
// etc... include the numerals so you don't have to converts some things to char not the rest...
};
// to lookup a character:
char item = 'A';
int number = lookup['A'];
To decode an phone number just split it into an array of char's and look them up one after the other
List<int> digits = new List<int>();
foreach (char c in inputString)
{
digits.Add(lookup[c]);
}
Im sure somebody will post a 1-liner using LINQ as well, but this is the vanilla version.
Using a string look up would shorten the code:--
String decode "--------------------------------01234567890------2223334445556667778889999---------------------------------"; //256 char string
numout = decode.substring((int) Char.GetNumericValue(userinput),1);
But it would be a lot less efficient than using a "case" statement. Less code does not mean less cpu.

String formatting

I can written an application which converts strings (made of numbers) from 8 - 12 characters in length (see examples below)
1404336133
4174728823
0587035281
Basically I want to convert the strings above into a specific format (stored in a config file) for the time being its as shown below.
<add key="Consumer_Code_Format_For_Code_Length_Eight" value="#### ####"/>
<add key="Consumer_Code_Format_For_Code_Length_Nine" value="### ### ###"/>
<add key="Consumer_Code_Format_For_Code_Length_Ten" value="### #### ###"/>
<add key="Consumer_Code_Format_For_Code_Length_Eleven" value="#### ### ###"/>
<add key="Consumer_Code_Format_For_Code_Length_Twelve" value="#### #### ####"/>
I am currently using the following code to format the codes ...
public static string FormatCode(string code)
{
switch (code.Length.ToString())
{
case "8":
string codeFormat = ConfigurationManager.AppSettings["Consumer_Code_Format_For_Code_Length_Eight"];
code = String.Format("{0:" + codeFormat + "}", Double.Parse(code));
break;
case "9":
codeFormat = ConfigurationManager.AppSettings["Consumer_Code_Format_For_Code_Length_Nine"];
code = String.Format("{0:" + codeFormat + "}", Double.Parse(code));
break;
case "10":
codeFormat = ConfigurationManager.AppSettings["Consumer_Code_Format_For_Code_Length_Ten"];
code = String.Format("{0:" + codeFormat + "}", Double.Parse(code));
break;
case "11":
codeFormat = ConfigurationManager.AppSettings["Consumer_Code_Format_For_Code_Length_Eleven"];
code = String.Format("{0:" + codeFormat + "}", Double.Parse(code));
break;
case "12":
codeFormat = ConfigurationManager.AppSettings["Consumer_Code_Format_For_Code_Length_Twelve"];
code = String.Format("{0:" + codeFormat + "}", Double.Parse(code));
break;
default:
codeFormat = ConfigurationManager.AppSettings["Consumer_Code_Format_For_Code_Length_Eight"];
code = String.Format("{0:" + codeFormat + "}", Double.Parse(code));
break;
}
// Finally return the newly formatted code
return code;
}
However, for the code 0587035281 it displays "58 7035 281" therefore removing the leading zero which I require.
Any ideas how to stop this and also is there anything wrong or suspicious with my code?
Looking forward to your reply
public static string FormatCode(string code)
{
switch (code.Length.ToString())
{
case "8":
string codeFormat = ConfigurationManager.AppSettings["Consumer_Code_Format_For_Code_Length_Eight"];
break;
case "9":
codeFormat = ConfigurationManager.AppSettings["Consumer_Code_Format_For_Code_Length_Nine"];
break;
case "10":
codeFormat = ConfigurationManager.AppSettings["Consumer_Code_Format_For_Code_Length_Ten"];
break;
case "11":
codeFormat = ConfigurationManager.AppSettings["Consumer_Code_Format_For_Code_Length_Eleven"];
break;
case "12":
codeFormat = ConfigurationManager.AppSettings["Consumer_Code_Format_For_Code_Length_Twelve"];
break;
default:
codeFormat = ConfigurationManager.AppSettings["Consumer_Code_Format_For_Code_Length_Eight"];
break;
}
char[] result = new char[codeformat.Length];
int used = 0;
for(i = 0; i < codeformat.Length; i++)
{
if (codeformat[i] == '#')
{
result[i] = code[used];
used++;
}
else
result[i] = codeformat[i];
}
// Finally return the newly formatted code
return new string(result);
}
Doublevalues are actually stored as numbers, so leading zeroes are being automatically removed when using Double.Parse().
Tho add the nleading zeroes once again, you can do something similar to this (not tested, written from the top of my head.) Remember the original length, then compare the result and add as many leading zeroes as required.
public static string FormatCode(string code)
{
int originalLength = code.Length;
switch (originalLength)
{
case 8:
string codeFormat = ...;
code = ...;
break;
case 9:
codeFormat = ...;
code = ...;
break;
// ...
while (code.Length < originalLength) {
code = "0" + code;
}
return code;
}
There's no pretty solution you can do inline, you'll have to do your own processing. Since this is not really a number you're dealing with, and maybe you may need to have some non-numeric literals there, best that you just insert a space every N characters. This would go something like this:
int chunkSize = 3;
string a = "0123456789";
int len = a.Length;
StringBuilder sb = new StringBuilder(len + len / chunkSize);
int firstIdx = len % chunkSize;
sb.Append(a.Substring(0, firstIdx));
sb.Append(" ");
for (int i = firstIdx; i < len; i += chunkSize)
{
sb.Append(a.Substring(i, chunkSize));
sb.Append(" ");
}
a = sb.ToString();

Categories