1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 生成大小写字母加数字混合ID与自定义进制转换

生成大小写字母加数字混合ID与自定义进制转换

时间:2024-08-10 11:28:44

相关推荐

生成大小写字母加数字混合ID与自定义进制转换

有时候可以在别的网站上看到类似于这样的ID : D6pPMSTjOFI, 关于数据库主键的选择园子里面也讨论过许多了,比如这篇 小议数据库主键选取策略(原创). 字符串作ID有时候还是有它的优点的,但是如何生成不重复且易于生成按索引顺序排列的ID呢. 原来我是用的 DateTime.Now.Ticks 可以产生一个long类型的时间刻度值,后来要用字符串的,就把这个转成16进制的, 当然也可以工作,但是似乎还是太长了一点,于是想到能不能创建自己的"进制数"呢,按unicode的编码,从小到大应该是数字, 大写字符,小写字符,把它们放在一起可以形成一个62元素的数组,这就可以构成一个"62进制"的数了.

不过没有看.net框架里面的进制转换实现方案,本人不才自己写了一个来玩, 目前看来还可以工作, 有兴趣的高手看看可以怎么改进改进.可以将int, uint, long, ulong(暂不支持负数转换)转换成字符型的值. 算法不是很难,因为ulong的最大值只需要11位的字符串就可以表示了因此结果采用一个11元素的字符串数组来装, 首先确定转换出来的数有几个位数,接着按从高到低的数位进行计算, 比如10进制里面的 520 = 5*10*10 + 2*10 + 0 , 因此计算过一位的值之后减去它再计算下一位的值,采用递归调用直到最低位.然后将字符串数组拼装成完整字符返回就完成了.

采用时间刻度生成的ID应该可以按索引顺序插入吧,会不会出现GUID那样数据越多,插入越慢的情况? 我觉得不会, 有待数据库专家论证.

要反向转换就比较容易了,代码就不再给出.

代码如下,

Code

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Text;

namespaceMyTest.Core

{

publicclassMyIdentityConverter

{

/**////<summary>

///用一个长度为11的数组用来存储最后的结果.

///</summary>

///<paramname="sq">当前幂次方</param>

///<paramname="data"></param>

///<returns></returns>

publicstring[]ConvertTo62(ulongorgin)

{

returnConvertTo62(newstring[11],-2,orgin);

}

publicstring[]ConvertTo62(intorgin)

{

returnConvertTo62(newstring[11],-2,(ulong)orgin);

}

publicstring[]ConvertTo62(uintorgin)

{

returnConvertTo62(newstring[11],-2,(ulong)orgin);

}

publicstring[]ConvertTo62(longorgin)

{

returnConvertTo62(newstring[11],-2,(ulong)orgin);

}

privatestring[]ConvertTo62(string[]desCode,intsq,ulongorgin)

{

if(sq==-1)

returndesCode;//递减时已经计算完低位.

if(desCode.Length!=11||orgin<0)

thrownewException("参数无效!");

if(sq==-2)//使用-2作为初始值.开始计算.

{

Console.WriteLine("初始值origin:"+orgin.ToString());

for(inti=1;i<data.Length;i++)

{

if(orgin<data[i])

{

sq=i;

break;

}

elseif(i==data.Length-1)

{

sq=11;

break;

}

}

Console.WriteLine("目标位数:"+sq.ToString());

}

if(sq<0)

thrownewException("出错啦");

intcurrnetChar=-1;

for(intk=0;k<62;k++)

{

if(orgin<(ulong)k*data[sq-1])

{

currnetChar=k-1;

orgin-=(ulong)(k-1)*data[sq-1];

Console.WriteLine("当前计算值:"+orgin);

break;

}

elseif(k==61)

{

currnetChar=61;

orgin-=(ulong)61*data[sq-1];

Console.WriteLine("当前计算值:"+orgin);

break;

}

}

Console.WriteLine("当前位字符索引:"+currnetChar.ToString());

desCode[11-sq]=charactor[currnetChar].ToString();

sq-=1;

if(sq>0)

returnConvertTo62(desCode,sq,orgin);

else

returndesCode;

}

staticreadonlyulong[]data=newulong[]{1,62,3844,238328,14776336,916132832,56800235584,3521614606208,218340105584896,13537086546263552,839299365868340224};

staticreadonlychar[]charactor=newchar[]{'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R',

'S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};

}

}

再附上单元测试 :

Code

[Test]

publicvoidConverterTest()

{

MyIdentityConverterconverter=newMyIdentityConverter();

string[]descode=converter.ConvertTo62(DateTime.Now.Ticks);

Console.WriteLine("转换结果:"+string.Join(string.Empty,descode));

string[]descode1=converter.ConvertTo62(int.MaxValue);

Console.WriteLine("转换结果:"+string.Join(string.Empty,descode1));

string[]descode2=converter.ConvertTo62(uint.MaxValue);

Console.WriteLine("转换结果:"+string.Join(string.Empty,descode2));

string[]descode3=converter.ConvertTo62(ulong.MaxValue);

Console.WriteLine("转换结果:"+string.Join(string.Empty,descode3));

DateTimedt=newDateTime(,12,20);//这里使用时间刻度来创建一个唯一的ID.

string[]descode4=converter.ConvertTo62(DateTime.Now.Ticks-dt.Ticks);

Console.WriteLine("转换结果:"+string.Join(string.Empty,descode4));

Assert.IsTrue(true);

}

在沙加的神舟本上完成的单元测试控制台输出:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。