Php ранд против Perl ранд - PullRequest
2 голосов
/ 08 июля 2011

Я пытаюсь портировать кусок кода с perl на php.Фрагмент кода на Perl является частью скрипта создания видео по запросу akamai.Сценарий генерирует начальное число на основе местоположения / URL-адреса видеофайла (который всегда будет постоянным для одного URL-адреса).И затем он используется при генерации серийного идентификатора для потока (который в основном является случайным числом от 1 до 2000 с использованием начального числа).Вот код perl.

$seed=6718;
srand($seed);
print(int(rand(1999)) + 1); // return 442 every time
И преобразованный код PHP:
$seed=6718;
srand($seed);
echo(rand(0, 1999) + 1); //returns 155 every time
Работает ли php rand иначе, чем perl?

Ответы [ 3 ]

8 голосов
/ 08 июля 2011

Да.Вы не можете зависеть от того, что их алгоритмы одинаковы.Для perl то, какой rand используется, зависит от того, для какой платформы был создан ваш perl.

Возможно, вам больше повезет, если использовать определенный алгоритм;например, Mersenne Twister, похоже, доступен для PHP и Perl .Обновление: попытка дает разные результаты, так что, по крайней мере, один из них не сработает.

Обновление 2: из отображаемых вами номеров perl ваш perl использует библиотеку drand48;Я не знаю, доступен ли он для PHP вообще, и Google не помогает.

2 голосов
/ 08 июля 2011

[clippy] Похоже, что вы пытаетесь хэшировать число, может быть, вы хотите использовать хеш-функцию? [/ Clippy]

Хеш-функции предназначены для ввода и получения последовательно повторяемого значения,это с виду случайное.В качестве бонуса они часто имеют межъязыковые реализации.

Использование srand() с rand() для получения того, что в основном является значением хеш-функции, является довольно плохой идеей.Разные языки используют разные алгоритмы, некоторые просто используют системные библиотеки.Изменение (или обновление) ОС, стандартной библиотеки C или языка может привести к совершенно разным результатам.

Использование SHA1 для получения числа от 1 до 2000 немного излишне, но вы по крайней мере можете быть уверены, чтоВы можете перенести код практически на любой язык и получить тот же результат.

use Digest::SHA1;

# get a integer hash value from $in between $min (inclusive) and $max (exclusive)
sub get_int_hash {
    my ($in, $min, $max) = @_;

    # calculate the SHA1 of $in, note $in is converted to a string.
    my $sha  = Digest::SHA1->new;
    $sha->add( "$in" );
    my $digest = $sha->hexdigest;
    # use the last 7 characters of the digest (28 bits) for an effective range of 0 - 268,435,455.
    my $value = hex substr $digest, -7;
    # scale and shift the value to the desired range.
    my $out = int( $value / 0x10000000 * ( $max - $min ) ) + $min;

    return $out;
}
print get_int_hash(6718, 1, 2000); #this should print 812 for any SHA1 implementation.
0 голосов
/ 08 июля 2011

Просто увидев этот фрагмент кода, невозможно сказать, если он такой же.

Сначала вам нужно знать, что даже генератор случайных чисел, такой как функция rand(), не является действительно случайным.Он вычисляет новое значение с математической формулой из предыдущего числа.С помощью функции srand() вы можете установить начальное значение.

Вызов srand() с одним и тем же аргументом каждый раз означает, что программа всегда возвращает одинаковые номера в одном и том же порядке.

Если вы действительно хотите случайные числа, в Perl вы должны удалить инициализацию srand().Поскольку Perl автоматически устанавливает srand() в лучшее (случайное) значение при первом вызове функции rand().

Если ваша программа действительно хочет случайные числа, то это также должно быть хорошо для PHP.Но даже в PHP я бы посмотрел, если srand() будет автоматически установлен и установлен на более случайное значение.

Если ваша программа не работает со случайными числами и вместо этого действительно хочет поток чисел, который всегдато же самое, тогда фрагмент кода, вероятно, не идентичны.Даже если вы выполняете ту же инициализацию с помощью srand (), возможно, PHP использует другую формулу для вычисления следующего «случайного» числа.

Так что вам нужно взглянуть на окружающий код, если код действительно хочет случайные числаЕсли да, вы можете использовать этот код.Но даже тогда вы должны искать лучшую инициализацию для srand ().

...