Преобразовать строку в непротиворечивую, но случайную 1 из 10 опций - PullRequest
1 голос
/ 10 октября 2019

У меня много строк. Каждая строка имеет вид... и т. д.

Мне нужно преобразовать каждую строку в случайное число 1-10. Каждый раз, когда эта строка преобразуется, она должна быть одинаковым числом. Выборка строк, даже с похожим текстом, должна привести к довольно равномерному разбросу значений 1-10.

Моей первой мыслью было сделать что-то вроде md5($string), а затем разбить af, 0-9 на десятьПримерно равные группы, определите, куда попадает первый символ хэша, и поместите его в эту группу. Но при этом, похоже, возникают проблемы при преобразовании 16 в 10 путем умножения на 0,625, но это приводит к неравномерному разбросу.

Мысли о хорошем методе последовательного преобразования строки в случайное / повторяемое число,1-10? Должен быть более легкий путь.

Ответы [ 2 ]

2 голосов
/ 10 октября 2019

Вот краткая демонстрация того, как вы можете это сделать.

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";
}

Как это работает :

В основном вы получаете выходные данные хеш-функции и уменьшаете еедо желаемого диапазона (в данном случае 1..10).

В приведенном выше примере я использовал хэш-функцию sha256, которая возвращает 32 байта произвольных двоичных данных. Затем я извлекаю только первые 4 байта как целочисленное значение (unpack()). На данный момент у меня есть 4-байтовое целочисленное значение (диапазон 0..4294967295). Чтобы уменьшить его до диапазона 1..10, я просто беру остаток от деления на 10 (0..9) и добавляю 1. Это не единственный способ уменьшить диапазон, но простой.

Итак, приведенный выше пример состоит из 3 шагов:

  1. получить значение хеша
  2. преобразовать значение хеша в целое число
  3. целочисленный диапазон уменьшения до нуля

Гораздо более короткий пример с функцией crc32(), которая сразу возвращает целочисленное значение, что позволяет нам пропустить шаг 2:

function getOneToTenHash($str) {
    $int = crc32($str); // 0..4294967295
    return ($int % 10) + 1; // 1..10
}
0 голосов
/ 10 октября 2019

ниже, может быть, то, что вы хотите

$inStr = "hello world";
$md5Str = md5($inStr);

$len = strlen($md5Str);
$out = 0;
for($i=0; $i>$len; $i++) {
    $out = 7*$out + intval($md5Str[$i]); // if you want more random, can and random() here
}

$out = $out % 10 + 1; // scope= [1,10]
...