将MySQL列值更新为随机的16个字母alphanum字符串

时间:2014-09-02 20:57:33

标签: php mysql sql

我在MySQL中创建了一个名为password_salt_c

的列

我想为数据库中的每条记录设置一个随机的16个字符的字母数字字符串。

有215,000条记录。我尝试在PHP中执行此操作,但它耗尽了服务器上的所有内存。

如何在MySQL中完成?

2 个答案:

答案 0 :(得分:0)

目前尚不清楚您实际想要解决的问题。 (我的回答故意忽略了您要填充的列的名称,并忽略了您提出的问题的上下文。)


如果我需要将“一个随机的,16个字符,字母数字的字符串”分配给一个列,对于表中的所有行,作为一次性的事情,我可能会做这样的事情:

UPDATE mytable SET mycol =
CONCAT(SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',FLOOR(1.0+RAND()*62),1)
      ,SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',FLOOR(1.0+RAND()*62),1)
      ,SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',FLOOR(1.0+RAND()*62),1)
      ,SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',FLOOR(1.0+RAND()*62),1)
      ,SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',FLOOR(1.0+RAND()*62),1)
      ,SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',FLOOR(1.0+RAND()*62),1)
      ,SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',FLOOR(1.0+RAND()*62),1)
      ,SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',FLOOR(1.0+RAND()*62),1)
      ,SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',FLOOR(1.0+RAND()*62),1)
      ,SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',FLOOR(1.0+RAND()*62),1)
      ,SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',FLOOR(1.0+RAND()*62),1)
      ,SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',FLOOR(1.0+RAND()*62),1)
      ,SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',FLOOR(1.0+RAND()*62),1)
      ,SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',FLOOR(1.0+RAND()*62),1)
      ,SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',FLOOR(1.0+RAND()*62),1)
      ,SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',FLOOR(1.0+RAND()*62),1)
      )

请注意,表达式 FLOOR(1.0+RAND()*62) 旨在返回1到62范围内的伪随机整数。这用作SUBSTR函数的参数,返回单个字母数字字符。敲掉十六次重复,连接结果......瞧...一个伪随机的16个字符的字母数字字符串。

答案 1 :(得分:0)

请不要尝试进行自己的安全编程。如果你犯了一点点错误,那么对于坏人来说,很难做到正确和容易破解。如果您正在生成自己的大量伪随机数,那么系统性错误就变得格外容易了。

相反,请查看PHP函数password_hashpassword_verify

这些函数不是存储单独的salt字段(如您所建议的那样),而是遵循在散列密码字符串中包含salt的惯例。 password_hash遵循随机化盐的加密最佳实践。

因此,当用户提供新的明文密码(更改或设置密码)时,您可以这样做:

$hashed_password = password_hash ( $plaintext, PASSWORD_DEFAULT ); 
unset ( $plaintext );

您应该将$hashed_password字符串存储在数据库的varchar(255)列中。该函数生成随机盐,然后将其与明文密码一起使用以生成散列密码,然后将salt和散列密码一起存储。通常,它按顺序运行哈希函数十次。

(我非常谨慎地使用unset()功能,以避免在RAM中保留明文密码的副本超过必要的时间。)

然后,稍后当用户提供密码以获得访问权限时,您可以执行以下操作:

if (password_verify( $plaintext, $hashed_password )) {
    /* the password is correct, grant access */
    unset( $plaintext );
    /* do what the user wanted to do. */
}
else {
   /* the password did not match */
}