V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
leonwong
V2EX  ›  问与答

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

  •  
  •   leonwong · 2013-07-26 17:39:24 +08:00 · 5711 次点击
    这是一个创建于 4120 天前的主题,其中的信息可能已经有所发展或是发生改变。
    字符串间不能冲突以及字符串中字母大小写不敏感
    第 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  
       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  
       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   ·   实用小工具   ·   998 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 21:22 · PVG 05:22 · LAX 13:22 · JFK 16:22
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.