我有很多弦。每个字符串类似于:
我需要能够将每个字符串转换为随机数,1-10。每次转换该字符串时,它都应该始终是相同的数字。对字符串进行采样,即使文本相似,也应该导致值 1-10 的分布相当均匀。
我的第一个想法是做类似的事情md5($string),然后将 af,0-9 分解为十个大致相等的组,确定散列的第一个字符落在哪里,并将其放入该组中。但这样做似乎在将 16 乘以 0.625 转换为 10 时存在问题,但这会导致分布不均匀。
关于将字符串一致转换为随机/可重复数字 1-10 的好方法的想法?必须有一种更简单的方法。
这是一个快速演示如何做到这一点。
function getOneToTenHash($str) {
$hash = hash('sha256', $str, true);
$unpacked = unpack("L", $hash); // convert first 4 bytes of hash to 32-bit unsigned int
$val = $unpacked[1];
return ($val % 10) + 1; // get 1 - 10 value
}
for ($i = 0; $i < 100; $i++) {
echo getOneToTenHash('str' . $i) . "\n";
}
Run Code Online (Sandbox Code Playgroud)
怎么运行的:
基本上,您可以获得哈希函数的输出并将其缩小到所需的范围(在本例中为 1..10)。
在上面的例子中,我使用了sha256哈希函数,它返回 32 字节的任意二进制数据。然后我只提取前 4 个字节作为整数值 ( unpack())。此时我有一个 4 字节整数值(0..4294967295 范围)。为了将其缩小到 1..10 范围,我只需将除以 10 (0..9) 的余数加 1。这不是缩小范围的唯一方法,但却是一种简单的方法。
因此,上面的示例包含 3 个步骤:
一个更短的示例,crc32()其函数立即返回整数值,从而允许我们省略步骤 2:
function getOneToTenHash($str) {
$int = crc32($str); // 0..4294967295
return ($int % 10) + 1; // 1..10
}
Run Code Online (Sandbox Code Playgroud)