有时候可以在别的网站上看到类似于这样的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
using System;
using System.Collections.Generic;
using System.Text;

namespace MyTest.Core
{
    public class MyIdentityConverter
    {
        /**//// <summary>
        /// 用一个长度为11的数组用来存储最后的结果.
        /// </summary>
        /// <param name="sq">当前幂次方</param>
        /// <param name="data"></param>
        /// <returns></returns>
        public string[] ConvertTo62(ulong orgin)
        {
            return ConvertTo62(new string[11], -2, orgin);
        }

        public string[] ConvertTo62(int orgin)
        {
            return ConvertTo62(new string[11], -2, (ulong)orgin);
        }

        public string[] ConvertTo62(uint orgin)
        {
            return ConvertTo62(new string[11], -2, (ulong)orgin);
        }

        public string[] ConvertTo62(long orgin)
        {
            return ConvertTo62(new string[11], -2, (ulong)orgin);
        }

        private string[] ConvertTo62(string[] desCode, int sq, ulong orgin)
        {
           
            if (sq == -1)
                return desCode;//递减时已经计算完低位.

            if (desCode.Length != 11 || orgin < 0)
                throw new Exception("参数无效!");

            if (sq == -2)//使用-2作为初始值. 开始计算.
            {
                Console.WriteLine("初始值origin : " + orgin.ToString());
                for (int i = 1; i < data.Length; i++)
                {
                    if (orgin < data[i])
                    {
                        sq = i ;
                        break;
                    }
                    else if (i == data.Length - 1)
                    {
                        sq = 11;
                        break;
                    }
 
                }
                Console.WriteLine("目标位数 : " + sq.ToString());
            }

            if (sq < 0)
                throw new Exception("出错啦");

            int currnetChar = -1;

            for (int k = 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;
                }
                else if (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)
                return ConvertTo62(desCode, sq, orgin);
            else
                return desCode;
        }

        static readonly ulong[] data = new ulong[] { 1, 62, 3844, 238328, 14776336, 916132832, 56800235584, 3521614606208, 218340105584896, 13537086546263552, 839299365868340224 };
        static readonly char[] charactor = new char[] { '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]
        public void ConverterTest()
        {
            MyIdentityConverter converter = new MyIdentityConverter();

            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));

            DateTime dt = new DateTime(2005, 12, 20);//这里使用时间刻度来创建一个唯一的ID.
            string[] descode4 = converter.ConvertTo62(DateTime.Now.Ticks - dt.Ticks);
            Console.WriteLine("转换结果 : " + string.Join(string.Empty, descode4));

            Assert.IsTrue(true);
        }

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

转载于:https://www.cnblogs.com/darkangle/archive/2008/02/15/1069743.html

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

  1. java生成大小写字母加数字的随机数

    项目中用到一授权码,网上搜索资源整理后发表 public class Random {/*** 生成32位大小写加数字随机数* @param args*/public static void main ...

  2. formValidator正则校验密码大小写字母加数字

    RegexValidator:   属性 属性名称 默认值 详细解释 regexp 正则表达式 "" 采用的是显式构造函数new RegExp("pattern" ...

  3. 新浪微博id的62进制转换

    某条微博链接 某条微博的链接如下,同样省略了后面的无关参数 http://weibo.com/2803301701/CeaOU15IT CeaOU15IT为这条微博的mid,与之相对应的还有一个id, ...

  4. 【Python 最全版(一)】—加解密、编码解码、进制转换、字符串转换

    点个赞留个关注吧!! <<请先安装这几个模块>> # Python 3.11.0 import hashlib import binascii import google_cr ...

  5. 使用id生成6位数(字母加数字),亲测不会重复

    使用id生成6位数(字母加数字),亲测不会重复 package cn.wkgb.common.utils; import java.util.HashMap; import java.util.Map ...

  6. python随机生成大写字母_python随机生成大小写字母数字混合密码(仅20行代码)

    用简单的方法生成随机性较大的密码 仅用20行代码随机生成密码 核心思路:利用random模块 random模块随机生成数字,大小写字母,循环次数 while循环+随机生成的循环次数-->随机pl ...

  7. php怎样规定密码混合,PHP产生随机字串,可用来自动生成密码 默认长度6位 字母和数字混合...

    /** * 产生随机字串,可用来自动生成密码 默认长度6位 字母和数字混合 * @param string $len 长度 * @param string $type 字串类型 * 0 字母 1 数字 ...

  8. php mysql 随机字符串函数是_PHP 生成随机字符串的方法函数, 默认长度6位 字母和数字混合件...

    PHP 生成随机字符串的方法函数, 默认长度6位 字母和数字混合件/** * 生成随机字符串,可用来自动生成密码 默认长度6位 字母和数字混合 * @param string $len 长度 * @p ...

  9. python编程实战(二):一文教你生成随机验证码!大小写字母与数字组合,位数可以控制

    随机验证码的生成 前言 正文 实现 代码 效果 前言 验证码验证,是常见的安全验证的一种方式,可以用来杜绝脚本和机器人操作等等: 除了本文介绍的简单的验证码之外,还有拼图验证.文字顺序验证等常见的验证 ...

最新文章

  1. SQL_Server_2005_日期和时间函数(描述及实例)
  2. matlab dsp实验报告,matlab实验报告14.pdf
  3. vue中用数组语法绑定class
  4. python之父子进程间通信
  5. 各种系统程序更新链接
  6. [Ext JS 4] 实战之Grid, Tree Gird编辑Cell
  7. pyhton 从web获取json数据 保存到本地然后再读取
  8. Vivaldi解决flash插件问题
  9. RAC中参数文件的配置
  10. UVA10049 Self-describing Sequence【数列】
  11. hdfs中8031是什么端口号_删了HDFS又能怎样?记一次删库不跑路事件
  12. 全球最厉害的14位程序员!你知道有哪几位?
  13. 华为交换机学习指南基于子网划分划分vlan
  14. My Eighty-third Page - 打家劫舍Ⅲ - By Nicolas
  15. Word文档如何从中间某一页开始设置页码
  16. 计算机应用基础实训报告excel,excel实验报告模板
  17. Halcon 算子 elliptic_axis
  18. 抗混叠滤波器 - ADC前端放大器和RC滤波器设计实现步骤
  19. [数据结构]递归树:借助树求解递归算法的时间复杂度
  20. python计算多维向量空间夹角余弦值

热门文章

  1. 唠唠SE的集合-10——Collections工具类
  2. App分享之微信微博等各个社交平台的分享授权规则和常见问题
  3. PHP中全局变量global和$GLOBALS[]的区别分析
  4. 优秀PHP在线教程收集
  5. mapredue输入路径
  6. kaptcha验证码实现,配合spring boot使用
  7. 刘启成_编写并使用shell脚本
  8. 深入剖析iLBC的丢包补偿技术(PLC)
  9. 8 月--菜鸟吐槽日志
  10. 团队项目第一阶段冲刺站立会议1(4月18日)