解码从Base36到十进制在c#
本文关键字:十进制 Base36 解码 | 更新日期: 2023-09-27 18:16:42
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";
我只能假设您的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
您在源代码上使用ToLower()
,并且您的列表仅包含大写字符,因此IndexOf('a')
返回-1。
我想你会想用ToUpper()
代替。
下面是递归函数:
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);
}
}
您可以使用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'));