用"指定字符组成的任意进制"转换生成不带4的卡号
单位让生成一批卡,但不能带4.
如想想生成1000张卡,想到的解决方法有两个:
方法一:
用一个while循环,先生成10进制字串,如果字串中包含4,跳过,然后继续. 直到生成1000张卡为止,跳出循环.
方法二:
用一个for循环,把每个数字转换成不包含4的进制数,完成
看来,方法二要感觉要简单点. 且不用浪费空循环了,如(400-499)这一百次.
要使用方法二,我们先要实现这个任意字符组成的任意进制的转换类.下面是我的实现:
public class BaseConverter
{
protected List<char> _chars = new List<char>();
protected Dictionary<char, int> _charmap = new Dictionary<char, int>();
protected List<long> _preBitValue = new List<long>();
/// <summary>
/// 得到进制指定权位的值
/// </summary>
/// <param name="pos">权位</param>
/// <returns>权位的数值</returns>
protected long GetPowerValue(int pos)
{
if (_preBitValue.Count < pos)
{
for (int i = _preBitValue.Count; i <= pos; ++i)
{
_preBitValue.Add(Convert.ToInt64(Math.Pow(_chars.Count, i)));
}
}
return _preBitValue[pos];
}
/// <summary>
/// 构造一个指定进制和字符的转换器
/// </summary>
/// <param name="baseChars">表示从0-N的字符序列</param>
public BaseConverter(char[] baseChars)
{
_chars.AddRange(baseChars);
for (int i = 0; i < baseChars.Length; ++i)
{
_charmap.Add(baseChars[i], i);
}
}
/// <summary>
/// 把用指定进制和字符的字串, 解释成等值的十进制数值
/// </summary>
/// <param name="value">指定进制和字符的字串</param>
/// <returns>等值的十进制数值</returns>
public long ToNumber(string value)
{
char[] chars = value.ToCharArray();
long ret = 0;
for (int i = 0; i < chars.Length; ++i)
{
ret += GetPowerValue(chars.Length - 1 - i) * _charmap[chars[i]];
}
return ret;
}
/// <summary>
/// 把当前十进制数值用指定的进制和字符表现出来
/// </summary>
/// <param name="value">十进制数值</param>
/// <returns>表现出来的字串</returns>
public string ToString(long value)
{
int power = _chars.Count;
List<char> list = new List<char>();
while (value > 0)
{
int l = Convert.ToInt32(value % power);
value /= power;
list.Add(_chars[l]);
}
list.Reverse();
return new string(list.ToArray());
}
}
{
protected List<char> _chars = new List<char>();
protected Dictionary<char, int> _charmap = new Dictionary<char, int>();
protected List<long> _preBitValue = new List<long>();
/// <summary>
/// 得到进制指定权位的值
/// </summary>
/// <param name="pos">权位</param>
/// <returns>权位的数值</returns>
protected long GetPowerValue(int pos)
{
if (_preBitValue.Count < pos)
{
for (int i = _preBitValue.Count; i <= pos; ++i)
{
_preBitValue.Add(Convert.ToInt64(Math.Pow(_chars.Count, i)));
}
}
return _preBitValue[pos];
}
/// <summary>
/// 构造一个指定进制和字符的转换器
/// </summary>
/// <param name="baseChars">表示从0-N的字符序列</param>
public BaseConverter(char[] baseChars)
{
_chars.AddRange(baseChars);
for (int i = 0; i < baseChars.Length; ++i)
{
_charmap.Add(baseChars[i], i);
}
}
/// <summary>
/// 把用指定进制和字符的字串, 解释成等值的十进制数值
/// </summary>
/// <param name="value">指定进制和字符的字串</param>
/// <returns>等值的十进制数值</returns>
public long ToNumber(string value)
{
char[] chars = value.ToCharArray();
long ret = 0;
for (int i = 0; i < chars.Length; ++i)
{
ret += GetPowerValue(chars.Length - 1 - i) * _charmap[chars[i]];
}
return ret;
}
/// <summary>
/// 把当前十进制数值用指定的进制和字符表现出来
/// </summary>
/// <param name="value">十进制数值</param>
/// <returns>表现出来的字串</returns>
public string ToString(long value)
{
int power = _chars.Count;
List<char> list = new List<char>();
while (value > 0)
{
int l = Convert.ToInt32(value % power);
value /= power;
list.Add(_chars[l]);
}
list.Reverse();
return new string(list.ToArray());
}
}
使用举例如下:
//十进制转换
BaseConverter bc = new BaseConverter("0123456789".ToCharArray());
Console.WriteLine(bc.ToNumber("456789"));
Console.WriteLine(bc.ToString(756217));
//没有4的九进制转换
bc = new BaseConverter("012356789".ToCharArray());
long val = bc.ToNumber("856789");
Console.WriteLine(val);
Console.WriteLine(bc.ToString(val));
//查看当前九进制下,两个号段之间有多少可用号
long v1 = bc.ToNumber("018512");
long v2 = bc.ToNumber("999999");
Console.WriteLine("还能有{0}张卡", v2 - v1);
//十六进制转换
BaseConverter bcchs = new BaseConverter("0123456789abcdef".ToCharArray());
Console.WriteLine(val);
Console.WriteLine(bcchs.ToString(0xefefef));
//下面看一下,都生成卡号从 3000000 开始的号,生成2000000 张
{
//进制转换方法
BaseConverter bc = new BaseConverter("012356789".ToCharArray());
long dtBegin = DateTime.Now.Ticks;
long min = bc.ToNumber("3000000");
long max = min + 2000000;
for (long i = min; i < max; ++i)
{
bc.ToString(i);
}
long dtEnd = DateTime.Now.Ticks;
Console.WriteLine(dtEnd - dtBegin);
}
{
//普通方法
long dtBegin = DateTime.Now.Ticks;
for (long i = 3000000, count = 0; count < 5000000; ++i)
{
string val = i.ToString();
if (val.IndexOf('4') >= 0)
continue;
++count;
}
long dtEnd = DateTime.Now.Ticks;
Console.WriteLine(dtEnd - dtBegin);
}
BaseConverter bc = new BaseConverter("0123456789".ToCharArray());
Console.WriteLine(bc.ToNumber("456789"));
Console.WriteLine(bc.ToString(756217));
//没有4的九进制转换
bc = new BaseConverter("012356789".ToCharArray());
long val = bc.ToNumber("856789");
Console.WriteLine(val);
Console.WriteLine(bc.ToString(val));
//查看当前九进制下,两个号段之间有多少可用号
long v1 = bc.ToNumber("018512");
long v2 = bc.ToNumber("999999");
Console.WriteLine("还能有{0}张卡", v2 - v1);
//十六进制转换
BaseConverter bcchs = new BaseConverter("0123456789abcdef".ToCharArray());
Console.WriteLine(val);
Console.WriteLine(bcchs.ToString(0xefefef));
//下面看一下,都生成卡号从 3000000 开始的号,生成2000000 张
{
//进制转换方法
BaseConverter bc = new BaseConverter("012356789".ToCharArray());
long dtBegin = DateTime.Now.Ticks;
long min = bc.ToNumber("3000000");
long max = min + 2000000;
for (long i = min; i < max; ++i)
{
bc.ToString(i);
}
long dtEnd = DateTime.Now.Ticks;
Console.WriteLine(dtEnd - dtBegin);
}
{
//普通方法
long dtBegin = DateTime.Now.Ticks;
for (long i = 3000000, count = 0; count < 5000000; ++i)
{
string val = i.ToString();
if (val.IndexOf('4') >= 0)
continue;
++count;
}
long dtEnd = DateTime.Now.Ticks;
Console.WriteLine(dtEnd - dtBegin);
}
由于中间有 4000000 的循环,所以还是进制转换方法优. 嘿嘿
PS:用这个方法,还可以用来加密哟:
BaseConverter bcchs = new BaseConverter("ksdfhjiy&^$#@)(".ToCharArray());
Console.WriteLine(bcchs.ToString(895621));
//你猜一下,会是什么?
Console.WriteLine(bcchs.ToString(895621));
//你猜一下,会是什么?
QQ:273352165
evlon#126.com
转载请注明出处。