DethoRhyne
DethoRhyne

Reputation: 980

How to perform mutliple Replace calls at once

I have a bit of a weird question here at hands. I have a text that's encoded in such a way that each character is replaced by another character and I'm creating an application that will replace each character with a correct one. But I've come across a problem that I have trouble solving. Let me show with an example:

Original text: This is a line.
Encoded text:  (.T#*T#*%*=T50;

Now, as I said, each character represents another character, '(' is 'T', '.' is actually a 'h' and so on.

Now I could just go with

string decoded = encoded.Replace('(','T'); //T.T#*T#*%*=T50;

And that will solve one problem, but when I reach character 'T' that is actually encoded character 'i' I will have to replace all 'T' with 'i', which means that all previously decoded letter 'T's (that were once '(') will also change along with the encoded 'T'.

//T.T#*T#*%*=T50; -> i.i#*i#*%*=i50;

in this situation it's obvious that I should've just went the other way around, first change 'T' to 'i' and then '(' to 'T', but in the text I'm changing that kind of analysis is not an option.

What's the alternative here that I could do to perform the task correctly?

Thank you!

Upvotes: 0

Views: 77

Answers (3)

David
David

Reputation: 218828

Using .Replace() probably isn't the way to go in the first place, since as you're finding it covers the whole string every time. And once you've modified the whole string once, the encoding is lost.

Instead, loop over the string one time and replace characters individually.

Create a function that accepts a char and returns the replaced char. For simplicity, I'll just show the signature:

private char Decode(char c);

Then just loop over the string and call that function on each character. LINQ can make short work of that:

var decodedString = new string(encodedString.Select(c => Decode(c)).ToArray());

(This is freehand and untested, you may or may not need that .ToArray() for the string constructor to be happy, I'm not certain. But you get the idea.)

If it's easier to read you can also just loop manually over the string and perhaps use a StringBuilder with each successive char to build the final decoded result.

Upvotes: 1

Chris Pickford
Chris Pickford

Reputation: 8991

Without knowledge of your encryption algorithm, this answer assumes that it's a simple character translation akin to the Caesar Cipher.

Pass in your encrypted string, the method loops over each character, adjusting it by the value of shiftDelta and returns the resulting string.

private string Decrypt(string input)
{
    const int shiftDelta = 10;

    var inputChars = input.ToCharArray();
    var outputChars = new char[inputChars.Length];

    for (var i = 0; i < outputChars.Length; i++)
    {
        // Perform character translation here
        outputChars[i] = (char)(inputChars[i] + shiftDelta); 
    }

    return outputChars.ToString();
}

Upvotes: 0

Andrey Korneyev
Andrey Korneyev

Reputation: 26846

One possible solution is do not use replace string method at all.

Instead you can create method which for every encoded character will output decoded one, and then go through your string as through array of char and for every character in this array use "decryption" method to get decoded character - thus you'll receive decoded string.

For example (using StringBulder to create new string):

private static char Decode(char source)
{
        if (source == '(')
            return 'T';
        else if (source == '.')
            return 'h';
        //.... and so on
}

string source = "ABC";

var builder = new StringBuilder();
foreach (var c in source)
    builder.Append(Decode(c));

var result = builder.ToString();

Upvotes: 2

Related Questions