我需要一种有效的方法来获得一个随机和唯一的字符串,重复的可能性为零(或可忽略不计).
我需要[0-9A-z]范围内的角色.
这是我到目前为止:
substr(sha1(mt_rand().uniqid()),0,22);
Run Code Online (Sandbox Code Playgroud)
因为我知道这实际上是在谈论bcrypt和密码salting现在我真的可以只是指出人们阅读它应该使用的功能而不是手动滚动他们自己的盐系统.
使用password_hash($input, PASSWORD_DEFAULT);产生适合插入到数据库中的哈希值.这将为你取盐.
插入:
$hash = password_hash($_POST["password"], PASSWORD_DEFAULT, ["cost" => 16]);
DB::table("users")->insert(["username" => $user, "password" => $hash]);
// or whatever database method you use to insert data
Run Code Online (Sandbox Code Playgroud)
验证:
$hash = DB::table("users")->fetchByName($username)->select("password");
$input = $_POST["password"];
$verified = password_verify($input, $hash); // true if the password matches
Run Code Online (Sandbox Code Playgroud)
在PHP 5.5之前的版本中,使用https://github.com/ircmaxell/password_compat作为插入1
当随机产生盐时,碰撞的几率是
1 / [number of possible letters/numbers] ** [length]
Run Code Online (Sandbox Code Playgroud)
这对于一个22个字符的字符串来说是不可能的低(好吧,不可能,但可忽略不计)
1 / (22 ** 60) = 1 / (3.51043 x 10**80)
Run Code Online (Sandbox Code Playgroud)
看到?很小.
如果你需要一个真正随机的字符串(注意:这些字符串只是一行数字映射到字母),那么你有点不走运.
您正在寻找的是CSPRNG(密码安全伪随机数发生器).不需要独特性.
正如@Guarav在他的回答中指出的那样,你可以使用时间戳作为你的种子然后哈希它.这称为UUID(唯一通用标识符,如果它是128位时间戳)是可预测的,并且可能由于多种原因而变坏:
然而,只要准确度足够,您仍然可以使用时间戳作为唯一的盐.不随机(除非你将它用作随机种子并将其转换为base10,这仍然是一个坏主意).如果您可以在纳秒内计算时间并将其用作唯一ID,那么请考虑这一点.PHP无法快速处理以提供两个冲突的亚纳秒ID 1(但这并不意味着您不应该验证!)
1:它与作曲家合作!
| 归档时间: |
|
| 查看次数: |
3224 次 |
| 最近记录: |