我需要将整数转换为base64字符表示。我正在使用OxA3的答案在这个线程:Quickest way to convert a base 10 number to any base in .NET?什么是转换为任意基的C#函数的高效反转?
我该如何反过来得到我原来的整数回到给定一个字符串?
我需要将整数转换为base64字符表示。我正在使用OxA3的答案在这个线程:Quickest way to convert a base 10 number to any base in .NET?什么是转换为任意基的C#函数的高效反转?
我该如何反过来得到我原来的整数回到给定一个字符串?
Joel Mueller's answer应该引导你的基础-64的情况下。
针对您在your own answer提供的初步代码,你绝对可以通过改变代码来完成你的for
循环做提高效率(有效的O(N)IndexOf
)使用哈希查找(这应该使它成为O(1))。
我基于这个假设baseChars
是您在您的类的构造函数中初始化的字段。如果这是正确的,做如下调整:在你的StringToInt
方法
private Dictionary<char, int> baseChars;
// I don't know what your class is called.
public MultipleBaseNumberFormatter(IEnumerable<char> baseCharacters)
{
// check for baseCharacters != null and Count > 0
baseChars = baseCharacters
.Select((c, i) => new { Value = c, Index = i })
.ToDictionary(x => x.Value, x => x.Index);
}
然后:
char next = encodedString[currentChar];
// No enumerating -- we've gone from O(N) to O(1)!
if (!characterIndices.TryGetValue(next, out nextCharIndex))
{
throw new ArgumentException("Input includes illegal characters.");
}
我在这里有一个工作版本的第一遍,尽管我不知道它有多高效。
public static int StringToInt(string encodedString)
{
int result = 0;
int sourceBase = baseChars.Length;
int nextCharIndex = 0;
for (int currentChar = encodedString.Length - 1; currentChar >= 0; currentChar--)
{
char next = encodedString[currentChar];
// For loop gets us: baseChar.IndexOf(char) => int
for (nextCharIndex = 0; nextCharIndex < baseChars.Length; nextCharIndex++)
{
if (baseChars[nextCharIndex] == next)
{
break;
}
}
// For character N (from the end of the string), we multiply our value
// by 64^N. eg. if we have "CE" in hex, F = 16 * 13.
result += (int)Math.Pow(baseChars.Length, encodedString.Length - 1 - currentChar) * nextCharIndex;
}
return result;
}
如果base-64真的是你需要的东西,而不是“任何基地”,那么你需要的是已经内置到框架中的一切:
int orig = 1337;
byte[] origBytes = BitConverter.GetBytes(orig);
string encoded = Convert.ToBase64String(origBytes);
byte[] decoded = Convert.FromBase64String(encoded);
int converted = BitConverter.ToInt32(decoded, 0);
System.Diagnostics.Debug.Assert(orig == converted);
神那丑不知道为什么人们狂欢这么多关于这个C#。 – ldog 2010-08-26 23:00:59
@ldog:哈哈,我无法想象任何曾经嘲笑过C#的人都会选择*将字符串转换为整数作为任意碱基*作为它真正闪耀的场景。事实上,将C#与C进行比较对我来说似乎毫无意义。假设我抱怨在C中快速开发一个丰富的GUI应用程序是多么困难,并问为什么有人喜欢它。 – 2010-08-26 23:20:13
它看起来不像是在工作。原始函数将(1,2,3,4)映射到(b,c,d,e);这个将它们映射到(AqAAAA,AgAAAA,AwAAAA,BAAAAA)。不是最初的意图,即使用较少的字符数字。 – ashes999 2010-08-27 16:39:29
下面是使用LINQ的功能和.NET Framework 4.0 zip扩展进行计算的一个版本。
public static int StringToInt(string encodedString, char[] baseChars) {
int sourceBase = baseChars.Length;
var dict = baseChars
.Select((c, i) => new { Value = c, Index = i })
.ToDictionary(x => x.Value, x => x.Index);
return encodedString.ToCharArray()
// Get a list of positional weights in descending order, calcuate value of weighted position
.Zip(Enumerable.Range(0,encodedString.Length).Reverse(), (f,s) => dict[f] * (int)Math.Pow(sourceBase,s))
.Sum();
}
仅供参考,在函数外计算字典对于大批转换更为有效。
下面是一个base10数字转换baseK并返回一个完整的解决方案:相比C.
public class Program
{
public static void Main()
{
int i = 100;
Console.WriteLine("Int: " + i);
// Default base definition. By moving chars around in this string, we can further prevent
// users from guessing identifiers.
var baseDefinition = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
//var baseDefinition = "WBUR17GHO8FLZIA059M4TESD2VCNQKXPJ63Y"; // scrambled to minimize guessability
// Convert base10 to baseK
var newId = ConvertToBaseK(i, baseDefinition);
Console.WriteLine(string.Format("To base{0} (short): {1}", baseDefinition.Length, newId));
// Convert baseK to base10
var convertedInt2 = ConvertToBase10(newId, baseDefinition);
Console.WriteLine(string.Format("Converted back: {0}", convertedInt2));
}
public static string ConvertToBaseK(int val, string baseDef)
{
string result = string.Empty;
int targetBase = baseDef.Length;
do
{
result = baseDef[val % targetBase] + result;
val = val/targetBase;
}
while (val > 0);
return result;
}
public static int ConvertToBase10(string str, string baseDef)
{
double result = 0;
for (int idx = 0; idx < str.Length; idx++)
{
var idxOfChar = baseDef.IndexOf(str[idx]);
result += idxOfChar * System.Math.Pow(baseDef.Length, (str.Length-1) - idx);
}
return (int)result;
}
}
@ ashes999足够公平..链接删除,并用代码替换回答。 – tbehunin 2016-02-16 22:27:50
使用字典是一个好主意。 – ashes999 2010-08-27 16:41:59