我需要使用PHP生成一个字符串,需要是唯一而需要是4到8个字符(值一个变量)。
我以为我可以使用crc32 hash但是我无法确定多少个字符,但确定它是唯一的。另一方面只创建一个“密码生成器”将生成重复的字符串,并检查表中的值,每个字符串将需要一段时间。
我该怎么做?
也许我可以使用它:
function unique_id(){
$better_token = md5(uniqid(rand(), true));
$unique_code = substr($better_token, 16);
$uniqueid = $unique_code;
return $uniqueid;
}
$id = unique_id();
更改为:
function unique_id($l = 8){
$better_token = md5(uniqid(rand(), true));
$rem = strlen($better_token)-$l;
$unique_code = substr($better_token, 0, -$rem);
$uniqueid = $unique_code;
return $uniqueid;
}
echo unique_id(4);
你认为我每次都会获得独特的弦乐吗?
答案 0 :(得分:46)
简而言之,我认为你会获得相当不错的随机价值。总是有碰撞的可能性,但你已经做了一切可以获得随机值。 uniqid()根据当前时间(以微秒为单位)返回随机值。指定rand()(mt_rand()会更好)并且第二个参数为true来表示uniqid()应该使值更加独特。使用md5()散列值也应该使它非常独特,因为即使生成的两个随机值的微小差异也应该通过散列函数放大。 idealmachine是正确的,因为较长的值不太可能发生碰撞,而不是较短的值。
您的函数也可能更短,因为md5()将始终返回一个32个字符长的字符串。试试这个:
function unique_id($l = 8) {
return substr(md5(uniqid(mt_rand(), true)), 0, $l);
}
答案 1 :(得分:3)
随机性问题是你永远无法确定任何事情。这次你有一个很小的机会获得一个数字,下一个数字相同。也就是说,您希望尽可能长地使字符串减少这种可能性。作为这些数字的长度的一个例子,GUIDs (globally unique identifiers)长16个字节。
理论上,四个十六进制字符(16位)仅提供16 ^ 4 = 65536种可能性,而八个十六进制字符(32位)给出16 ^ 8 = 4294967296。但是,您需要考虑它的可能性< em>任何两个哈希要碰撞(“生日问题”)。维基百科对这种碰撞的可能性有good table。简而言之,四个十六进制字符肯定是不够的,八个可能不是。
您可能需要考虑使用Base64编码而不是十六进制数字;这样,你可以输入48位而不是32位。
八个字节是8 * 8 = 64位。
答案 2 :(得分:0)
可靠密码您只能使用 ascii 字符 a-zA-Z 和数字0-9 。要做到这一点,最好的方法是使用加密安全方法,例如PHP7中的 random_int()或 random_bytes()。其余功能为 base64_encode()您只能将其用作支持函数,以使字符串可靠,并将其更改为 ASCII 字符。
mt_rand()不安全且非常老。 从任何字符串您必须使用random_int()。从二进制字符串您应该使用base64_encode()使二进制字符串可靠或bin2hex,但是然后您将字节仅切换到16个位置(值)。 See my implementation of this functions.