Is it possible to "reverse" php str_shuffe? - php

I was just wondering if it's possible to reverse the string shuffle function in php?
For Example:
$shuffle = str_shuffle("popcorn");
echo $shuffle;
If you refreshed the page 3 times, you might see something like this:
oroppcn
oppncro
opcrnop
etc...
Is there a way to "Scrabble" that back into "popcorn"?

If we are talking about canceling the str_shuffle action, then this is not possible despite the fact that the php documentation says: "This function does not generate cryptographically secure values". Reversing the rand algorithm used in str_shuffle is a non-trivial cryptographic task.
But let's fantasize. Suppose if we have a dictionary, then we can do this:
<?php
$list = array('apple', 'popcorn', 'banana');
$shuffle = str_shuffle("popcorn");
$letters = count_chars($shuffle,1);
foreach ($list as $word) {
if ($letters == count_chars($word,1))
echo "$word\n";
}
DEMO

Related

Is there any manual method other than "str_repeat" to repeat the string?

I mean if we give 3, b as parameters passed into function, it should return "bbb" by using loops.
I've tried some code, but I do not want to post it because it might look crazy for a well-versed developer. I can provide you links, this question has been asked in an interview, mainly they want it to be computed in C or C++. Since I am a PHP practitioner, I am curious to know it is possible in PHP. Below is the link (ROUND 2: SIMPLE CODING(3 hours))
https://www.geeksforgeeks.org/zoho-interview-set-3-campus/
A PHP function to do that would probably look like this:
function string_repeat($num, $string)
{
$result = "";
for ($x = 0; $x < $num; $x++) {
$result .= $string;
}
return $result;
}
So calling echo string_repeat(3, 'b'); would output:
bbb
One way would be to keep around a "dummy" string, of sufficient length to be longer than any string you want to generate. Then, we can use preg_replace to replace each character with whatever the input is. Finally, we can substring that replace string to the desired length.
$dummy = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
$length = 3;
$dummy = preg_replace('/./', 'b', $dummy);
$output = substr($dummy, 0, $length);
echo $output;
This prints:
bbb
You could wrap this into a helper function, if you really wanted to do that. Note that internally the regex engine is most likely doing some looping of its own, so we are not really freeing ourselves from looping, just hiding it from the current context.

PHP "randomize" the rand() function?

Hi everyone I was wondering what could be possible to randomize this code even further :
<?php
$key=md5('ILOVEYOU');
$serverseed = floor(time() / 5);
srand($serverseed);
$result = rand();
$modulus_result= $result % 100;
echo "before: ".$modulus_result."<br>";
echo "after: ".encrypt($modulus_result, $key)."<br>";
echo decrypt($modulus_result, $key);
function decrypt($string, $key){
$string = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, base64_decode($string), MCRYPT_MODE_ECB));
return $string;
}
function encrypt($string, $key){
$string = rtrim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $string, MCRYPT_MODE_ECB)));
return $string;
}
?>
Ok for everyone that stumbled upon this thread and missunderstood the topic, I'm not using this function to protect ANYTHING inside my website, I'm just looking ways to randomize this function as it uses time() as a reference...
I need to generate a random int from 1-100, that seems to work, I'm just looking for other ways to randomize it( if I could explain a bit more, adding some sort of "salt" not encryption of any sort.)
Check the documentation:
This function does not generate cryptographically secure values, and
should not be used for cryptographic purposes. If you need a
cryptographically secure value, consider using random_int(),
random_bytes(), or openssl_random_pseudo_bytes() instead.
You might want to use random_int instead.
The problem with that is that was introduced with PHP 7 so you might not be able to use it. In this case, you can get it here, as mentioned in the documentation.

How to find out how many variable variables there are and randomise?

I've created a collection of variable variables using a foreach loop and I want to find out how many there are; and then select one with pseudo randomness.
Example code:
$count = 0;
foreach ($a as $key => $b) {
$count++;
$new_stuff["stuff" . $count] = $b;
}
extract($new_stuff);
I can then echo out each stuff, like this:
echo $stuff1[0];
or...
echo implode($stuff1); (this one gives me double the result)
I want to find out how many $stuff variables there are* and then pick one with one with rand(). Is it somehow possible to construct a variable from two parts, like this pseudocode: $stuff = "stuff" and attaching, say, number 5 so that it becomes $stuff5?
*I can find out the number of elements that create the various $stuff variables by using this:
$shift = rand(0, count($a));
array_rand is an option but rand() is not a very reliable random number generator.
Assuming your keys are numeric, it would be better to use mt_rand() with count().
$random = $a[ mt_rand(0, count($a)-1) ];

Sorting PHP Randomised numbers by size

So I've got this:
$h = $user_goals;
while($h > 0) {
randomScorer();
$minute = rand(0,90);
echo "(".$minute.")<br>";
$h--;
Basically, what it does is, $user_goals, has a load of factors drawn into it and creates a number, between 0-5, and this information is used to generate the times of the goals, using the above PHP function.
It's working, it's brilliant, etc. However, the numbers are appearing in random order in which they are generated and so I was wondering:
Is there any way to sort these numbers?
Would I put them into an array during this iteration methodology, and then sort the array by the number's value?
Any help is greatly appreciated!
That is why PHP provides us Sort functions. Have a look here.
<?php
$fruits = array("lemon", "orange", "banana", "apple");
sort($fruits);
?>
Since your array is NUMERIC, you need to use the FLAG along with the sort function.
sort($goals, SORT_NUMERIC);
print_r($goals);
Same idea, using sort() but also uses range and array_walkto set up your array a little closer to how you already do it:
$goal_array = range(1, $user_goals); // Warning, assumes $user_goals is number
array_walk($goal_array, function(&$goal) {
randomScorer();
$goal = rand(0,90);
});
sort($goal_array, SORT_NUMERIC);

Is this a fair method of algorithm comparison?

I wanted to convert an array to lowercase and was wondering the most efficient method. I came up with two options, one using array_walk and one using foreach and wanted to compare them. Is this the best way to compare the two? Is there an even more efficient method that I have overlooked?
<?
$a = array_fill(0, 200000, genRandomString());
$b = array_fill(0, 200000, genRandomString());
$t = microtime(true);
array_walk($a, create_function('&$a', '$a = strtolower($a);'));
echo "array_walk: ".(microtime(true) - $t);
echo "<br />";
$t = microtime(true);
foreach($b as &$source) { $source = strtolower($source); }
echo "foreach: ".(microtime(true) - $t);
function genRandomString($length = 10) {
$characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
$string = '';
for ($p = 0; $p < $length; $p++) {
$string .= $characters[mt_rand(0, strlen($characters)-1)];
}
return $string;
}
The output:
array_walk: 0.52975487709045
foreach: 0.29656505584717
Two questions in one!
How to run the tests:
Personally, I'd write individual test scripts for each method, then use the Apache ab utility to run the tests:
ab -n 100 -c 1 http://localhost/arrayWalkTest.php
ab -n 100 -c 1 http://localhost/foreachTest.php
That gives me a much more detailed set of statistics for comparison
I'd also try to ensure that the two methods were working on identical datasets for each test, not different random data.
The most efficient method:
You should unset($source) after your loop as a safety measure: because you're accessing by reference in the loop, $source will still contain a reference to the last entry in the array and may give you unpredictable results if you reference $source anywhere else in your script.
I had lots of weird results in the past when using the microtime approach over using a dedicated profiler, like it exists in XDebug or Zend_Debugger. Also, for a fair comparison your arrays should be identical instead of two random arrays.
In addition, you could consider using array_map and strtolower:
$a = array_map('strtolower', $a);
which would save you the lambda for array_walk. Anonymous functions created with create_function (unlike PHP 5.3's anonymous functions) are known to be slow and strtolower is a native function, so using it directly should be faster.
I did a quick benchmark and I dont see any relevant speed difference between this approach and your foreach. Like so often, I'd say it's a µ-opt. Of course, you should test that in a real world application if you think it matters. Synthetic benchmarks are fun, but ultimately useless.
On a sidenote, to change the array keys, you can use
array_change_key_case — Changes all keys in an array
I don't know PHP, so this is a wild guess:
str_split(strtolower(implode("", $a)))

Categories