把10进制转换成36进制,或者64进制。可以用更短的字符来表式更大范围的数据。
比如说我们的Url短连接。 在用6个字符就可以表达 68719476736这么大的空间。比int.MaxValue还大了.
还有我们早期的系统还会使用一些推荐码之类的。我们如果直接给出用户的ID或者名字,可能会让别人输入得很辛苦,所以我们可能就需要变成36进制。 这样别人输入的时候会方便一些。
public class ScaleConverter
{
private char[] chars;
private Dictionary<char, int> dict;
public int length;
public ScaleConverter(string scaleString = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
{
// OI 有一些字体的OI 跟 01是看不清楚的。
// 0123456789ABCDEFGHJKLMNPQRSTUVWXYZ
this.chars = scaleString.ToCharArray();
this.dict = ToCharDict(this.chars);
this.length = this.chars.Length;
}
public string ToCurrent(int num)
{
string curr = "";
while (num >= length)
{
curr = chars[num % length] + curr;
num = num / length;
}
curr = chars[num] + curr;
return curr;
}
public int ToInt32(string current)
{
double num = 0;
for (int i = 0; i < current.Length; i++)
{
num += dict[current[i]] * Math.Pow(length, current.Length - 1 - i);
}
return Convert.ToInt32(num);
}
// 跟据位数获取最小的数
public int GetMinmumNumber(int length)
{
var minmumChars = new char[length];
minmumChars[0] = chars[1];
for (int i = 1; i < length; i++)
{
minmumChars[i]= chars[0];
}
return this.ToInt32(new string(minmumChars));
}
private static Dictionary<char, int> ToCharDict(char[] chars)
{
var dic = new Dictionary<char, int>();
for (int i = 0; i < chars.Length; i++)
{
dic.Add(chars[i], i);
}
return dic;
}
}
推荐码有时候我们不希望这个代码从0开始。而是从1000开始。这样我就可以把这个"1000"转回我们的10进制数。让所有的用户ID加上这个数字,这样就可以达到这种效果了。
示例
void Main()
{
var scale= new ScaleConverter();
var current = scale.ToCurrent(10000); //7ps
var i = scale.ToInt32(current); //变成了10000
Console.WriteLine(i+" "+current);
}
int64版本
public class ScaleConverter
{
private char[] chars;
private Dictionary<char, int> dict;
public int length;
/// <summary>
/// scale chars does not have O and I
/// </summary>
/// <param name="scaleString"></param>
public ScaleConverter(string scaleString = "0126789345BQPSUWRTVXYZADCFEHGJKLNM")
{
// normal string 0123456789ABCDEFGHJKLMNPQRSTUVWXYZ
this.chars = scaleString.ToCharArray();
this.dict = ToCharDict(this.chars);
this.length = this.chars.Length;
}
public string ToCurrent(long num)
{
string curr = "";
while (num >= length)
{
curr = chars[num % length] + curr;
num = num / length;
}
curr = chars[num] + curr;
return curr;
}
public long ToInt64(string current)
{
double num = 0;
for (int i = 0; i < current.Length; i++)
{
num += dict[current[i]] * Math.Pow(length, current.Length - 1 - i);
}
return Convert.ToInt64(num);
}
public long GetMinmumNumber(int length)
{
if (length < 1)
{
return 0;
}
var minmumChars = new char[length];
minmumChars[0] = chars[1];
for (int i = 1; i < length; i++)
{
minmumChars[i] = chars[0];
}
return this.ToInt64(new string(minmumChars));
}
public long GetMaximumNumber(int length)
{
if (length < 1)
{
return 0;
}
var maximumChars = new char[length];
var lastChar =chars.Last();
for (int i = 0; i < length; i++)
{
maximumChars[i] = lastChar;
}
return this.ToInt64(new string(maximumChars));
}
private static Dictionary<char, int> ToCharDict(char[] chars)
{
var dic = new Dictionary<char, int>();
for (int i = 0; i < chars.Length; i++)
{
dic.Add(chars[i], i);
}
return dic;
}
}