用"指定字符组成的任意进制"转换生成不带4的卡号

介绍了一种通过自定义进制转换类生成不含数字4的卡号的方法,并对比了两种不同生成策略的效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

单位让生成一批卡,但不能带4.
  如想想生成1000张卡,想到的解决方法有两个:
  方法一:
    用一个while循环,先生成10进制字串,如果字串中包含4,跳过,然后继续. 直到生成1000张卡为止,跳出循环.
  方法二:
    用一个for循环,把每个数字转换成不包含4的进制数,完成

  看来,方法二要感觉要简单点. 且不用浪费空循环了,如(400-499)这一百次.
  要使用方法二,我们先要实现这个任意字符组成的任意进制的转换类.下面是我的实现:

None.gif    public class BaseConverter
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif{
InBlock.gif        
protected List<char> _chars = new List<char>();
InBlock.gif        
protected Dictionary<charint> _charmap = new Dictionary<charint>();
InBlock.gif        
protected List<long> _preBitValue = new List<long>();
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 得到进制指定权位的值
InBlock.gif        
/// </summary>
InBlock.gif        
/// <param name="pos">权位</param>
ExpandedSubBlockEnd.gif        
/// <returns>权位的数值</returns>

InBlock.gif        protected long GetPowerValue(int pos)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (_preBitValue.Count < pos)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
for (int i = _preBitValue.Count; i <= pos; ++i)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    _preBitValue.Add(Convert.ToInt64(Math.Pow(_chars.Count, i)));
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
return _preBitValue[pos];
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 构造一个指定进制和字符的转换器
InBlock.gif        
/// </summary>
ExpandedSubBlockEnd.gif        
/// <param name="baseChars">表示从0-N的字符序列</param>

InBlock.gif        public BaseConverter(char[] baseChars)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            _chars.AddRange(baseChars);
InBlock.gif
InBlock.gif            
for (int i = 0; i < baseChars.Length; ++i)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                _charmap.Add(baseChars[i], i);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 把用指定进制和字符的字串, 解释成等值的十进制数值
InBlock.gif        
/// </summary>
InBlock.gif        
/// <param name="value">指定进制和字符的字串</param>
ExpandedSubBlockEnd.gif        
/// <returns>等值的十进制数值</returns>

InBlock.gif        public long ToNumber(string value)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
char[] chars = value.ToCharArray();
InBlock.gif
InBlock.gif            
long ret = 0;
InBlock.gif            
for (int i = 0; i < chars.Length; ++i)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                ret 
+= GetPowerValue(chars.Length - 1 - i) * _charmap[chars[i]];
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
return ret;
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 把当前十进制数值用指定的进制和字符表现出来
InBlock.gif        
/// </summary>
InBlock.gif        
/// <param name="value">十进制数值</param>
ExpandedSubBlockEnd.gif        
/// <returns>表现出来的字串</returns>

InBlock.gif        public string ToString(long value)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
int power = _chars.Count;
InBlock.gif            List
<char> list = new List<char>();
InBlock.gif
InBlock.gif            
while (value > 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
int l = Convert.ToInt32(value % power);
InBlock.gif                value 
/= power;
InBlock.gif
InBlock.gif                list.Add(_chars[l]);
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            list.Reverse();
InBlock.gif
InBlock.gif            
return new string(list.ToArray());
ExpandedSubBlockEnd.gif        }

ExpandedBlockEnd.gif    }

None.gif

   使用举例如下:

None.gif            //十进制转换
None.gif
            BaseConverter bc = new BaseConverter("0123456789".ToCharArray());
None.gif            Console.WriteLine(bc.ToNumber(
"456789"));
None.gif            Console.WriteLine(bc.ToString(
756217));
None.gif
None.gif            
//没有4的九进制转换
None.gif
            bc = new BaseConverter("012356789".ToCharArray());
None.gif            
long val = bc.ToNumber("856789");
None.gif            Console.WriteLine(val);
None.gif            Console.WriteLine(bc.ToString(val));
None.gif            
None.gif            
//查看当前九进制下,两个号段之间有多少可用号
None.gif
            long v1 = bc.ToNumber("018512");
None.gif            
long v2 = bc.ToNumber("999999");
None.gif            Console.WriteLine(
"还能有{0}张卡", v2 - v1);
None.gif            
None.gif            
//十六进制转换
None.gif
            BaseConverter bcchs = new BaseConverter("0123456789abcdef".ToCharArray());
None.gif            Console.WriteLine(val);
None.gif            Console.WriteLine(bcchs.ToString(
0xefefef));
None.gif            
None.gif            
//下面看一下,都生成卡号从 3000000 开始的号,生成2000000 张
ExpandedBlockStart.gifContractedBlock.gif
            dot.gif{
InBlock.gif                
//进制转换方法
InBlock.gif
                BaseConverter bc = new BaseConverter("012356789".ToCharArray());
InBlock.gif                
long dtBegin = DateTime.Now.Ticks;
InBlock.gif
InBlock.gif                
long min = bc.ToNumber("3000000");
InBlock.gif                
long max = min + 2000000;
InBlock.gif
InBlock.gif                
for (long i = min; i < max; ++i)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    bc.ToString(i);
ExpandedSubBlockEnd.gif                }

InBlock.gif
InBlock.gif                
long dtEnd = DateTime.Now.Ticks;
InBlock.gif                Console.WriteLine(dtEnd 
- dtBegin);
ExpandedBlockEnd.gif            }

None.gif            
ExpandedBlockStart.gifContractedBlock.gif            
dot.gif{
InBlock.gif                
//普通方法
InBlock.gif
                long dtBegin = DateTime.Now.Ticks;
InBlock.gif                
for (long i = 3000000, count = 0; count < 5000000++i)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
InBlock.gif                    
string val = i.ToString();
InBlock.gif                    
if (val.IndexOf('4'>= 0)
InBlock.gif                        
continue;
InBlock.gif
InBlock.gif                    
++count;
ExpandedSubBlockEnd.gif                }

InBlock.gif
InBlock.gif                
long dtEnd = DateTime.Now.Ticks;
InBlock.gif                Console.WriteLine(dtEnd 
- dtBegin);
ExpandedBlockEnd.gif            }

None.gif
None.gif

       由于中间有 4000000 的循环,所以还是进制转换方法优. 嘿嘿


PS:用这个方法,还可以用来加密哟:

   
None.gif            BaseConverter bcchs = new BaseConverter("ksdfhjiy&^$#@)(".ToCharArray());
None.gif            Console.WriteLine(bcchs.ToString(
895621));
None.gif
None.gif
//你猜一下,会是什么?
None.gif

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值