在C#中从Base36解码为十进制

时间:2011-12-02 10:49:43

标签: c#

public static Int64 Decode(string input)
        {
            var reversed = input.ToLower().Reverse();
            long result = 0;
            int pos = 0;
            foreach (char c in reversed)
            {
                result += CharList.IndexOf(c) * (long)Math.Pow(36, pos);
                pos++;
            }
            return result;
        }

我正在使用一种方法将base36中的值解码为十进制。该方法工作正常 但是当我解码输入值“000A”时,事情就开始出错了 将其解码为-1。

有人能看出出了什么问题吗?我真的很困惑代码及其工作原理。

private const string CharList = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

4 个答案:

答案 0 :(得分:5)

我只能假设您的CharList不包含A,因此IndexOf(c)会返回-1以表明找不到该字符。请注意,默认情况下IndexOf区分大小写,因此,如果您在CharList中使用小写,而c使用大写,则不会匹配。

// pos = 0
result += CharList.IndexOf(c) * (long)Math.Pow(36, pos);
// pos = 36^0 = 1
// CharList.IndexOf(c) gives -1 when not found
// therefore, it equates to:
result += -1 * 1

答案 1 :(得分:2)

您在源代码上使用ToLower(),而您的列表仅包含大写字符,因此IndexOf('a')返回-1。

我认为你想要改用ToUpper()

答案 2 :(得分:0)

您可以使用Linq简洁地执行此任务,并且完全避免使用CharList。支持从任何基数(2到36)转换到基数10,如下所示:

string b36 = "000A", tbase = 36;
int b10 = b36
       .Select(d => d >= '0' && d <= '9' ? d - '0' : 10 + char.ToUpper(d) - 'A')
       .Aggregate(0, (pos, d) => pos * tbase + d);

为了完整性(从基地10到任何基地):

int value = 10, tbase = 36;
string result = "";
while (value > 0)
{
    int x = value % tbase;
    result = (char)(x >= 0 && x <= 9 ? x + 48 : x + 'A' - 10) + result;
    value /= tbase;
}
Console.WriteLine(result.PadLeft(4,'0'));

答案 3 :(得分:0)

这是一个递归函数:

using System;

class Program {
   static int decode(string sIn, int nBase) {
      int n = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".IndexOf(sIn[^1]);
      string s = sIn[..^1];
      return s != "" ? decode(s, nBase) * nBase + n : n;
   }

   static void Main() {
      var s = "q3ezbz";
      var n = decode(s, 36);
      Console.WriteLine(n == 1577858399);
   }
}