请问如何将自增id通过某种算法映射得出6位既包含字母又包含数字的随机字符串? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
leonwong
V2EX    问与答

请问如何将自增id通过某种算法映射得出6位既包含字母又包含数字的随机字符串?

  •  
  •   leonwong 2013-07-26 17:3924 +08:00 6146 次点击
    这是一个创建于 4467 天前的主题,其中的信息可能已经有所发展或是发生改变。
    字符串间不能冲突以及字符串中字母大小写不敏感
    第 1 条附言    2013-07-26 18:34:49 +08:00
    最好能体现多一点随机性,不希望六位字符串中全是数字或者是字符
    34 条回复    1970-01-01 08:00:00 +08:00
    rwx
        1
    rwx  
       2013-07-26 18:12:28 +08:00   1
    自增ID -> 无限
    6位字符串 -> 有限
    把无限集映射到有限集这种事。。
    qiayue
        2
    qiayue  
    PRO
       2013-07-26 18:21:07 +08:00
    数字 0-9 10个
    字母 a-z 26个
    字母 A-Z 26个
    字符 _和- 2个

    用以上字符按照 64 (10 + 26 + 26 +2 = 64) 进制与自增 ID 进行一一对应

    另外,64^6 = 68719476736 ,最多 687 亿数据

    要想更多数据,增大进制,也就是增多字符即可
    qiayue
        3
    qiayue  
    PRO
       2013-07-26 18:22:53 +08:00
    没看清楚字母大小写不敏感,那么,就只能是去掉大写字母,成了 38 进制了
    leonwong
        4
    leonwong  
    OP
       2013-07-26 18:31:32 +08:00
    @rwx 自增肯定有限,有长度限制
    leonwong
        5
    leonwong  
    OP
       2013-07-26 18:34:02 +08:00
    @qiayue 那其实这样就是一个38进制的值的自增,我想体现多点随机性,最好这六位中不要出现纯数字,这种方式映射必然会出现纯数字的情况
    jybox
        6
    jybox  
       2013-07-26 18:36:21 +08:00
    MD5取前6位...
    lichao
        7
    lichao  
       2013-07-26 18:37:58 +08:00
    @leonwong 你既然是随机,就必然有纯数字的,虽然比例很低
    @jybox 没试过,只有前 6 位,安全吗?
    leonwong
        8
    leonwong  
    OP
       2013-07-26 18:44:27 +08:00
    @jybox 会撞车吧,不能撞车
    rrfeng
        9
    rrfeng  
       2013-07-26 18:45:08 +08:00
    我估计你的自己设计算法了……
    leonwong
        10
    leonwong  
    OP
       2013-07-26 18:45:22 +08:00
    @lichao 我的意思就是不希望由另一个自增来取代这个自增,想增加点随机性
    leonwong
        11
    leonwong  
    OP
       2013-07-26 18:45:49 +08:00
    @rrfeng 就是不会设计才请教你们的,各位大大
    lichao
        12
    lichao  
       2013-07-26 18:46:16 +08:00
    @rrfeng 你可以自己做个试验,从 1 到 10 亿,MD5 取前 6 位试试,看有没有重复的,没有的话,就算是安全的
    leonwong
        13
    leonwong  
    OP
       2013-07-26 18:48:41 +08:00
    微博短链接貌似很符合我的要求,谁能把短链接算法跟我说说,麻烦了
    leonwong
        14
    leonwong  
    OP
       2013-07-26 18:49:29 +08:00
    @lichao 好,这个值得一试,我个人要求百万数据就足够了
    binux
        15
    binux  
       2013-07-26 19:04:55 +08:00
    将6位字符按照一定的规律选出一定量,随机洗牌,存下来
    不够了,再选一定的量,随机洗牌,存下来
    shiny
        16
    shiny  
       2013-07-26 19:28:01 +08:00
    @leonwong 短链的算法是可以逆向的,如果要随机还是 @binux 的方案靠谱。
    msg7086
        17
    msg7086  
       2013-07-27 16:20:19 +08:00
    @leonwong http://ra.gg/!iMD4o 我实现的。
    leonwong
        18
    leonwong  
    OP
       2013-07-28 09:32:11 +08:00
    @lichao 经过漫长的测试,插入79026值时候,md5前六位和前面有所重复
    leonwong
        19
    leonwong  
    OP
       2013-07-28 09:36:00 +08:00
    @shiny 其实逆向我觉得没关系,可以逆向,所以我也没有非要用MD5不可,@binux 算法能保证唯一性吗?
    leonwong
        20
    leonwong  
    OP
       2013-07-28 09:37:42 +08:00
    @msg7086 有点大神的感觉,我研究下
    79bxh9b
        21
    79bxh9b  
       2013-07-28 09:52:09 +08:00
    id转成字符串,前面用0补足位数,再把id字符串反转,再一步base58编码
    想更随机只要给base58的字典做随机乱序就行
    binux
        22
    binux  
       2013-07-28 10:25:41 +08:00
    @leonwong 当然
    leonwong
        23
    leonwong  
    OP
       2013-07-28 13:26:06 +08:00
    @binux 这样算法代价会不会有点高,存储代价也挺高的
    shiny
        24
    shiny  
       2013-07-28 13:27:55 +08:00
    @leonwong 如果短网址代码就能满足需求,有个好处是足够简单,能够直接互转。以下是我写的 PHP 版本和 python 版本,最初生成的 PHP 算法来源于 phurl。

    http://gist.github.com/shiny/6097499
    http://gist.github.com/shiny/6097505
    binux
        25
    binux  
       2013-07-28 13:28:01 +08:00
    @leonwong 你的id肯定对应一些数据吧,比如说数据库的某一行。把字符串存起来,用id查也是查,用映射后的串查也是查,有什么不同?
    leonwong
        26
    leonwong  
    OP
       2013-07-28 13:28:12 +08:00
    @79bxh9b base算法不太了解,能麻烦说说原理和特点是什么吗?
    shiny
        27
    shiny  
       2013-07-28 13:28:33 +08:00
    leonwong
        28
    leonwong  
    OP
       2013-07-28 13:32:32 +08:00
    @shiny 感谢提供代码!!定当好好捉摸!
    leonwong
        29
    leonwong  
    OP
       2013-07-28 13:46:29 +08:00
    @binux 有点道理!我需要另外建立一张表来存储映射关系吗?这样就有点像独立标签这样了,那这些标签要按照一定规律保持唯一性,算法怎么实现?
    binux
        30
    binux  
       2013-07-28 15:27:11 +08:00
    @leonwong 认真读我第一个回复
    79bxh9b
        31
    79bxh9b  
       2013-07-28 18:49:24 +08:00
    @leonwong 其实楼上shiny贴的代码就是base算法,只是用了54个字符。
    base58就是用了58个字符的版本,123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ
    manoon
        32
    manoon  
       2013-07-28 20:38:28 +08:00
    mongodb 不就是这样的么?
    leonwong
        33
    leonwong  
    OP
       2013-07-29 00:24:47 +08:00
    @binux 其实我的意思是不太明白随机洗牌怎么实现?
    leonwong
        34
    leonwong  
    OP
       2013-07-29 00:30:47 +08:00
    @79bxh9b 原来如此,我百度了下,很少对base算法有系统介绍,学习了
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2709 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 09:40 PVG 17:40 LAX 02:40 JFK 05:40
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86