Php radomize

67 %
33 %
Information about Php radomize
Technology

Published on March 16, 2014

Author: do_aki

Source: slideshare.net

Description

第5回 闇php勉強会

PHP と 乱打舞図 2014/03/15 第5回 闇PHP勉強会 do_aki

@do_aki http://do-aki.net/

title was born from typo らんだまいず 乱打舞図 モテカルロ法っぽくない?

randomize • 無秩序に並び替えること • 規則性がないこと • 偏りがないこと

http://nmi.jp/archives/541 (http://www.lauradhamilton.com/random- lessons-online-poker-exploit)

randomize function in php shuffle str_shuffle

give it try (php 5.5.10) function bench($name, $suffle_func) { $result = []; for ($i=0; $i<60000;++$i) { $a = range(1, 3); $suffle_func($a); $r = implode('', $a); $result[$r]=isset($result[$r])? $result[$r]+1 : 1; } print "{$name}¥n"; ksort($result); print_r($result); }

shuffle / str_shuffle bench("shuffle", "shuffle"); bench("str_shuffle", function(&$ary) { $str = str_shuffle(implode('', $ary)); $ary = str_split($str, 1); });

result of shuffle shuffle Array ( [123] => 9873 [132] => 10104 [213] => 9999 [231] => 9944 [312] => 9998 [321] => 10082 )

result of str_shuffle str_shuffle Array ( [123] => 9956 [132] => 9928 [213] => 10080 [231] => 9969 [312] => 10149 [321] => 9918 )

No Problem (in current version of php)

過去の shuffle は等分散ではなかった

implementation of shuffle(current version) long n_elems, rnd_idx, n_left; char temp; /* The implementation is stolen from array_data_shuffle */ /* Thus the characteristics of the randomization are the same */ n_elems = len; if (n_elems <= 1) { return; } n_left = n_elems; while (--n_left) { rnd_idx = php_rand(TSRMLS_C); RAND_RANGE(rnd_idx, 0, n_left, PHP_RAND_MAX); if (rnd_idx != n_left) { temp = str[n_left]; str[n_left] = str[rnd_idx]; str[rnd_idx] = temp; } } ext/standard/string.c より抜粋 / shuffle の実装も同じ

implementation of shuffle (php < 4.3.0) PHP_FUNCTION(shuffle){ zval *array; if (zend_parse_parameters(1 TSRMLS_CC, "a", &array) == FAILURE){ RETURN_FALSE; } if (zend_hash_sort(Z_ARRVAL_PP(&array), (sort_func_t)php_mergesort, array_data_shuffle, 1 TSRMLS_CC) == FAILURE) { RETURN_FALSE; } RETURN_TRUE; } } static int array_data_shuffle(const void *a, const void *b TSRMLS_DC) { return (php_rand(TSRMLS_C) % 2) ? 1 : -1; }

_人人人人人人人人人人人人_ > ランダムマージソート <  ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄

implementation of str_shuffle (php < 4.3.0) PHP_FUNCTION(str_shuffle) { /* Note : by using current php_string_shuffle for string */ /* with 6 chars (6! permutations) about 2/3 of them are */ /* computed for 6! calls for the function. So it isn't so */ /* unique. The ratio is the same for other lengths. */ char *str; int i, str_len; i = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) { RETURN_FALSE; } zend_qsort((void *)str, str_len, sizeof(char), php_string_shuffle TSRMLS_CC); RETURN_STRINGL(str, str_len, 1); }

implementation of str_shuffle (php < 4.3.0) static int php_string_shuffle(const void *a, const void *b TSRMLS_DC) { long rnd; rnd = php_rand(TSRMLS_C); if (rnd % 3) return 1; else if (rnd % 5) return 0; else return -1; }

_人人人人人人人人人人人人人人人_ > ランダム(?) クイックソート <  ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄

emulate old shuffle (php) bench("old_shuffle", function(&$ary){ usort($ary, function($a, $b) { return (rand() % 2) ? 1 : -1; }); }); bench("old_str_shuffle", function(&$ary){ usort($ary, function($a, $b) { $rnd = rand(); if ($rnd % 3) { return 1; } elseif ($rnd % 5) { return 0; } else { return -1; } }); });

result old_shuffle Array ( [123] => 22358 [132] => 7627 [213] => 3771 [231] => 3827 [312] => 7487 [321] => 14930 ) old_str_shuffle Array ( [123] => 30982 [132] => 4453 [213] => 5994 [231] => 2928 [312] => 8979 [321] => 6664 )

現在の shuffle は、本当に問題ないのか?

php_rand(C) := rand (php)

random in php rand mt_rand

rand vs mt_rand • rand – libc の random or lrand48 or rand – environment dependent • mt_rand – Mersenne Twister (MT19937) – implementation dependent

re-imprement of shuffle (environment independent) function mt_shuffle(&$ary) { $n = count($ary); while(--$n) { $rnd_idx = mt_rand(0, $n); if ($rnd_idx != $n) { $tmp = $ary[$n]; $ary[$n] = $ary[$rnd_idx]; $ary[$rnd_idx] = $tmp; } } }

Conclusion • 現在の shuffle / str_shuffle は、均等に分配 される • 異なる環境での再現性が必要なら mt_rand つかって再実装しよう • php 4 はオワコン

End Of Slide Let’s enjoy PHP hack life ;-)

Add a comment

Related presentations

Related pages

PHP: shuffle - Manual

shuffle (PHP 4, PHP 5, PHP 7) shuffle — Shuffle an array. Description. bool shuffle ( array &$array) This function shuffles (randomizes the order of the ...
Read more

RANDOM.ORG - True Random Number Service

RANDOM.ORG offers true random numbers to anyone on the Internet. The randomness comes from atmospheric noise, which for many purposes is better than the ...
Read more

Research Randomizer

Research Randomizer is a free resource for researchers and students in need of a quick way to generate random numbers or assign participants to ...
Read more

Randomize Background Image | CSS-Tricks

Randomize Background Image 1. Above the DOCTYPE. Set up and array of filenames, which correspond to the file names of the images you are trying to randomize.
Read more

MS Excel: How to use the RANDOMIZE Function (VBA)

This Excel tutorial explains how to use the Excel RANDOMIZE function with syntax and examples. The Microsoft Excel RANDOMIZE function allows you to change ...
Read more

C# Shuffle Array List - Visual C# Kicks

C# Shuffle Array Shuffle List. Unfortunately there is no automatic way to randomize, or shuffle, an array in C#. Yet all the pieces needed to mix a list ...
Read more

How to randomize (shuffle) a JavaScript array? - Stack ...

How to randomize (shuffle) a JavaScript array? up vote 556 down vote favorite. 175. I have one array like this: var arr1 = ["a", "b", "c", "d"];
Read more

Pokémon Randomizer - Universal Pokemon Game Randomizer

Why use this randomizer? It's universal. Every main series Pokemon game released in the US is supported, from Red to Black2 and everything in between.
Read more

MyFameandFortune.com | Facebook

Every Monday's at 12 noon, we are raffling out One Year Membership to MyFameandFortune the country's largest Model Portal. www.myfameandfortune.com
Read more