0

I need to convert a few lines of PHP code to C#. However, I have only basic knowledge and I don't understand well the arrays yet.

Here is the code that I need to be converted to C#:

function decode_char($c, $a1, $a2)
{
  $result = $c;
  for($j = 0; $j < count($a1); $j++) {
    if ($c == $a1[$j][0]) {
      $result = $a2[$j][0];
      break;
    }
    if ($c == $a2[$j][0]) {
      $result = $a1[$j][0];
      break;
    }
  }
  return $result;
}

function decode_str($s)
{
  $a1 = array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "W", "G", "X", "M", "H", "R", "U", "Z", "I", "D", "=", "N", "Q", "V", "B", "L");
  $a2 = array("b", "z", "a", "c", "l", "m", "e", "p", "s", "J", "x", "d", "f", "t", "i", "o", "Y", "k", "n", "g", "r", "y", "T", "w", "u", "v");

  $result = '';
  for($i = 0; $i < strlen($s); $i++) {
    $result .= decode_char($s[$i], $a1, $a2);
  }
  $result = base64_decode($result);
  return $result;
}

Here's what I've got so far:

public string decode_str(string s)
{
       string[] a1 = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "W", "G", "X", "M", "H", "R", "U", "Z", "I", "D", "=", "N", "Q", "V", "B", "L" };
       string[] a2 = { "b", "z", "a", "c", "l", "m", "e", "p", "s", "J", "x", "d", "f", "t", "i", "o", "Y", "k", "n", "g", "r", "y", "T", "w", "u", "v" };

       string result = "";
       for (int i = 0; i < s.Length; i++)
       {
           result += decode_char(s[i], a1, a2);
       }

           return result;
}

Can someone help with converting decode_char?

Thank you for fast answers. I already did it myself but using strings and not chars, so I will accept an answer tomorrow when I will revise my code.

2
  • Are you saying that you still need to convert decode_char()? Commented Feb 3, 2012 at 22:25
  • @M3NTA7 yes, i still need to convert that function and I'm not sure that what i have already done is correct. Commented Feb 3, 2012 at 22:27

4 Answers 4

1

This should be the equivalent of decode_char

public char decodeChar(char c, string[] a, string[] a2)
{
    for(var j = 0; j < a.Length; j++)
    {
        if(c == a1[j])
            return a2[j];
        if(c == a2[j])
            return a1[j];
    }
    return c;
}
Sign up to request clarification or add additional context in comments.

4 Comments

You forgot to return something if c is not found in a1 or a2.
...and var result = c; is not useful :)
You people! I just went line by line for the original function. I guess I should have proof read more.
... and you're comparing a char to a string; that's illegal. You can compare to the character that is the first index of the string.:)
1

I'll take a stab at rewriting decode_char; it's not that difficult...

public char decode_char(char input, string[] array1, string[] array2)
{
  var result = input;
  for(var j = 0; j < array1.Length; j++) 
  {
    if (input == array1[j][0]) {
      result = array2[j][0];
      break;
    }
    if (input == array2[j][0]) {
      result = array1[j][0];
      break;
    }
  }
  return result;
}

This will work with what you have already. HOWEVER, I see room for improvement. In C#, there is a semantic difference between a char and a string[1]. If you define your arrays as arrays of characters instead of arrays of strings, they no longer have to be "two-dimensional"; you can simply refer to the index of the character instead of the index of the first character of the string at a given index.

You also generally shouldn't use += with strings in C#. Strings are immutable; one instance is created, and if it is changed a new instance is created and the reference held by the variable is moved to the new instance; the old instance then hangs around until GCed. The upshot is that each += operation creates a brand new string, all but one of which are almost immediately useless, which is a waste of memory. Instead, there is a class called StringBuilder which reduces this "thrashing" and economizes on memory:

Also, it's bad practice to define an empty string literal. That gets created as a constant, unique and separate from all other defined literals, again wasting memory. The String.Empty constant available on the String class is a centralized variable that represents the empty string literal.

Lastly, C# best practices say to name your variables descriptively. C, S, A1 and A2 are not great identifiers.

public string decode_str(string input)
{
       char[] array1 = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'W', 'G', 'X', 'M', 'H', 'R', 'U', 'Z', 'I', 'D', '=', 'N', 'Q', 'V', 'B', 'L' };
       char[] array2 = { 'b', 'z', 'a', 'c', 'l', 'm', 'e', 'p', 's', 'J', 'x', 'd', 'f', 't', 'i', 'o', 'Y', 'k', 'n', 'g', 'r', 'y', 'T', 'w', 'u', 'v' };

       StringBuilder result = new StringBuilder(String.Empty);
       for (int i = 0; i < input.Length; i++)
       {
           result.Add(decode_char(input[i], array1, array2));
       }

       return result.ToString();
}

Lastly, C# has some extra tricks that PHP apparently does not which can make your decode_char function a bit more concise:

public char decode_char(char input, char[] array1, char[] array2)
{
  return array1.Contains(input) 
     ? array2[array1.IndexOf(input)]
     : array2.Contains(input)
        ? array1[array2.IndexOf(input)];
        : input;         
}

Comments

0

Try with this:

char decode_char(char c, string a1, string a2)
{
    for (int i = 0; i < a1.Length; i++)
    {
        if (c == a1[i]) return a2[i];
        if (c == a2[i]) return a1[i];
    }
    return c;
}
string decode_str(string s)
{
    const string a1 = "0123456789WGXMHRUZID=NQVBL";
    const string a2 = "bzaclmepsJxdftioYkngryTwuv";
    StringBuilder sb = new StringBuilder();
    foreach (char c in s)
        sb.Append(decode_char(c, a1, a2));
    return DecodeFrom64(sb.ToString());
}
string DecodeFrom64(string encodedData)
{
    byte[] encBytes = Convert.FromBase64String(encodedData);
    return Text.Encoding.Unicode.GetString(encBytes);
}

Comments

0

It's easy:

String DecodeChar(char c, string[] a1, string[] a2) {
  for(int i=0; i<a1.length; ++i) {
    if(a1[i] == c) return a2[i];
    if(a2[i] == c) return a1[i];
  }
  return c;
}

or:

String DecodeChar(char c, string[] a1, string[] a2) {
  var a1Id = Array.IndexOf(a1.ToCharArray(), c);
  var a2Id = Array.IndexOf(a2.ToCharArray(), c);
  if(a1Id != -1 && a1Id < a2Id) return a2[a1Id];
  if(a2Id != -1 && a2Id < a1Id) return a1[a1Id];
  return c;
}

1 Comment

Your lack of curly brackets on the for loop means you are just looping on the first if statement. You also never return something is c is not found in a1 or a2.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.