V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Victor215
V2EX  ›  程序员

这儿有一个伪需求

  •  
  •   Victor215 · 2017-08-23 23:31:42 +08:00 · 4329 次点击
    这是一个创建于 2435 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在有一个伪需求,按道理来讲是不可能提出来的,但是也可以想想。

    需求: 设计一个密码储存的方式可以支持两个密码登陆同一个账户,但是密码的储存只能用一个字段。

    直接能想到的就是可以把两个密码用分隔符连在一起,但是除了这种方式还有什么更好的方案么?有没有啥数学上的算法是支持的?

    33 条回复    2017-08-25 07:02:11 +08:00
    misaka20038numbe
        1
    misaka20038numbe  
       2017-08-23 23:43:36 +08:00   ❤️ 1
    新增除密码不一样其他都一样的行。
    frankyzf
        2
    frankyzf  
       2017-08-24 00:25:20 +08:00 via Android   ❤️ 1
    密码单独建张表?
    widewing
        3
    widewing  
       2017-08-24 01:06:59 +08:00 via Android   ❤️ 1
    直接连的方案哪儿不好了?
    lydasia
        4
    lydasia  
       2017-08-24 01:12:33 +08:00 via iPhone   ❤️ 1
    数学上?两个大质数的积这种?
    qiayue
        5
    qiayue  
       2017-08-24 01:13:26 +08:00   ❤️ 1
    不需要根据密码来查询账户,所以连在一起是最好的办法
    而且如果密码处理成同样位数字符串,连接符都不需要,直接根据长度切分就可以
    SpikeKnox
        6
    SpikeKnox  
       2017-08-24 01:15:34 +08:00 via Android   ❤️ 1
    反向想下,手机号或用户名同一密码都能登录。存法不同,当 ID 是密码,I 手机号和用户名就是两个不同密码
    blankme
        7
    blankme  
       2017-08-24 01:26:27 +08:00 via Android   ❤️ 1
    不可能的

    你所存储的字段最基本的要求是,无法反推出密码

    假设用户设置了密码 p1,映射到字段 s。那他如何设置任意密码 p2,同样能映射到 s...
    msg7086
        8
    msg7086  
       2017-08-24 01:48:32 +08:00   ❤️ 1
    @blankme 不需要映射到 s。
    只需要 f(p1)和 f(p2)都能被 g(s)确认就行。
    blankme
        9
    blankme  
       2017-08-24 01:57:55 +08:00   ❤️ 1
    @msg7086
    你说的“确认”是什么意思?确认就是=的意思吧。。。
    就假设你说的确认是另一个函数 h 好了
    f(p1) = h(g(s)) -> g^-1(h^-1(f(p1))) = s
    msg7086
        10
    msg7086  
       2017-08-24 02:17:33 +08:00   ❤️ 1
    @blankme 比如说 g(s) 得到一个数组,同时包含 f(p1) 和 f(p2)。只需要 Array.include? 即可确认。
    msg7086
        11
    msg7086  
       2017-08-24 02:20:40 +08:00   ❤️ 1
    PS: 其实这不是伪需求。
    大概在十年前的时候,有个网页城建游戏 Travian,其中有个机制叫做代管,即是设置另外一个密码并把账号交给别人管理,相比主密码来说权限有限制(比如不能进行自毁操作,不能内购等等),这就是典型的多密码登录需求。
    blankme
        12
    blankme  
       2017-08-24 02:27:34 +08:00 via Android   ❤️ 1
    @msg7086
    这种方法和楼主提到的两个密码(加密字段)连在一起并没区别。
    把多组数据存到一个单元里,或存到多个单元里,只是选用的数据结构,或者说实现方法不一样。理论上是等价的。。。
    geelaw
        13
    geelaw  
       2017-08-24 03:32:36 +08:00   ❤️ 1
    @blankme 考虑一个简单加盐的方法,每个用户有一个盐 s 和两个密码 p1, p2,hash H 的输出是定长,密码在数据库里面用

    H(p1s)H(p2s)

    存储,通过验证当且仅当传入的密码 p 使 H(ps) 是这个存储的值的前缀或后缀。

    楼主需要定义什么叫“数学上的算法”,才能获得自己满意的解答(当然前提是题主需要知道什么样的解答“令自己满意”且能够表达出来),因为拼接字符串也是数学的。
    willakira
        14
    willakira  
       2017-08-24 03:56:05 +08:00   ❤️ 1
    存成多条数据最好
    查询的时候需要 hash(user+password)
    你这样连在一起存的话,以后要管理不同密码权限的时候就麻烦了
    msg7086
        15
    msg7086  
       2017-08-24 04:51:01 +08:00   ❤️ 1
    我想了一下。
    假如密码 Hash 以后是 16 字节数据的话。
    要把两个 16 字节数据存进单个 16 字节的存储器。
    本身从信息学角度来说就已经不可能了吧。
    huluhulu
        16
    huluhulu  
       2017-08-24 08:42:03 +08:00 via iPhone   ❤️ 1
    10 楼是对的,针对 15 楼的疑问,可用缩短 hash 长度,或者增大密码表长度限制解决。
    debye
        17
    debye  
       2017-08-24 08:48:31 +08:00   ❤️ 1
    需求的前面部分合理,就是可以有多密码
    后面要一个字段存储不合理,为了后期扩展权限等功能,可以建立一个独立的表来存储密码
    lrh3321
        18
    lrh3321  
       2017-08-24 08:52:19 +08:00   ❤️ 1
    @msg7086 代管账号权限受限制了的话,不就相当于搞了个子账号给别人用吗。用代管的密码登上去的和原账号不等价啊。
    FanWall
        19
    FanWall  
       2017-08-24 09:27:11 +08:00 via Android   ❤️ 1
    和 secret sharing 很相似?数据在三维的某个点,通过包含这个点的任意三个平面就可以确定这个点

    但是这种一般是派发密钥给用户的
    zhongkouwei
        20
    zhongkouwei  
       2017-08-24 09:34:08 +08:00   ❤️ 1
    楼主的意思是:是否存在某种数学关系,使 f(x1)=y 同时 f(x2)=y。应该是种非对称加密,但是没有好的办法
    tscat
        21
    tscat  
       2017-08-24 09:40:23 +08:00   ❤️ 1
    只能间接的存两个密码
    lixiangzaizheli
        22
    lixiangzaizheli  
       2017-08-24 09:41:00 +08:00   ❤️ 1
    一楼挺好的 除了数据量会大一点 验证后识别为同一用户就好了
    ruchee
        23
    ruchee  
       2017-08-24 09:47:23 +08:00   ❤️ 1
    单独建表比较合理,防备以后有可能的扩展需求
    hekunhotmail
        24
    hekunhotmail  
       2017-08-24 09:47:36 +08:00   ❤️ 1
    分隔符 存一个字段里 然后代码处理喽
    whatafuck
        25
    whatafuck  
       2017-08-24 09:50:03 +08:00   ❤️ 1
    哈哈,其实就是,主密码和观看密码,主密码有一切权限,观看密码只能观看不能操作。。right ?
    jyf
        26
    jyf  
       2017-08-24 09:51:36 +08:00   ❤️ 1
    没有什么存储上的问题 一般大系统的用户登录都只是根据账户密码来获取一个认证与对应的用户 id 而已

    假如你的 认证表里的字段有三个 比如 alias, password, uid ,alias 是账户名称, password 是密码 uid 是用户 id

    把 alias,password 做个联合的 unique 那这个直接存储即可 没有啥难点
    ioth
        27
    ioth  
       2017-08-24 09:51:37 +08:00   ❤️ 1
    你们公司负责需求的是伪娘吗?
    wweir
        28
    wweir  
       2017-08-24 09:58:08 +08:00 via Android   ❤️ 1
    那么问题来了,真的只要存两个密码吗?
    真?那签个需求不变动协议,不为别的,就为计算工作量+方便打脸
    假?那要存几个密码?
    有固定数字,那就该用固定的列来存,该撕逼撕逼,该改表结构改表结构。
    不知道要存几个,那还是老老实实字符拼接吧,其它实现未必就简单。记得拼接字符用不可作为密码的字符
    wq2016
        29
    wq2016  
       2017-08-24 10:13:21 +08:00   ❤️ 2
    密码和用户字段互换
    密码作为真正的用户名字段
    而用户名作为密码字段,用户名可以多个
    Victor215
        30
    Victor215  
    OP
       2017-08-24 10:25:05 +08:00
    想了想,看来还是再来一张映射表是最佳的选择。
    msg7086
        31
    msg7086  
       2017-08-24 23:38:07 +08:00   ❤️ 1
    @lrh3321 没错,就是子账号。但用户名是相同的,只有密码不同。
    msg7086
        32
    msg7086  
       2017-08-24 23:39:55 +08:00   ❤️ 1
    @wweir 存 Hash 不需要考虑作为密码的字符……
    wweir
        33
    wweir  
       2017-08-25 07:02:11 +08:00 via Android   ❤️ 1
    @msg7086 单个密码可以不考虑。存多个密码拼接的时候,没法存拼接后的密码的 hash,得存 hash 后拼接的字符串。这样就得考虑长度了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1045 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 19:31 · PVG 03:31 · LAX 12:31 · JFK 15:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.