我需要將整數轉換爲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