I'm actually stuck with a idea. So what I want to create is the following:
1) Create a array of hash algorithms like:
$methods = array('md5()', 'base64_encode()', 'hex2bin()');
2) Loop through the algorithm permutations and generate a output like:
Method: md5 > md5 > md5 > base64_encode > md5 = Output the hash of md5(md5(md5(base64_encode(hex2bin(md5($value))))));
The amount of the used array positions should be randomized and the order also.
For example:
Output 1: md5(md5($value));
Output 2: md5(base64_encode(md5($value)));
And so on...
My problem is the following: I've been trying to put the amount of items to the end of each array position as u can see in the code. But somehow this is the result: http://pr0b.com/sqlx/documents/list/hashr.php
It puts the braces to each item sadly. The code looks like:
<?php
$pass = 'test';
$array_elems_to_combine = array('md5(', 'base64_encode(', 'hex2bin(');
$size = rand(0,10);
$current_set = array('');
for ($i = 0; $i < $size; $i++) {
$tmp_set = array();
foreach ($current_set as $curr_elem) {
foreach ($array_elems_to_combine as $new_elem) {
$tmp_set[] = $curr_elem . $new_elem . $pass . str_repeat(')', $size);
}
}
$current_set = $tmp_set;
}
foreach ($current_set as $key) {
echo($key) . '</br>';
}
?>
How about
<?php
$value = 'foobar';
$methods = array('md5', 'base64_encode', 'sha1');
for ($k = 0; $k < 5; $k++) {
$nb_recursions = rand(0, 5);
$result = recurse_on_methods($methods, $nb_recursions, $value);
echo ' = ' . $result . "\n";
}
function recurse_on_methods($methods, $recursions, $value)
{
$method_no = rand(0, count($methods) - 1);
$method = $methods[$method_no];
if ($recursions > 0) {
echo $method . ' > ';
return $method(recurse_on_methods($methods, $recursions - 1, $value));
} else {
echo $method . '(' . $value . ')';
return $method($value);
}
}
Sample output
sha1 > base64_encode > sha1(foobar) = b1322e636ae45c163be50b28f8cb6e51debf341e
base64_encode > sha1 > md5 > sha1 > md5 > md5(foobar) = ZDBkMzY4YWI4NjRjY2FlNGRmNTAzMGM0NTg5ZmFjZjQ5MmI0MTc2YQ==
md5(foobar) = 3858f62230ac3c915f300c664312c63f
md5 > md5 > md5 > base64_encode > sha1(foobar) = 694a8dd41c13868abb9c6300ec87413a
sha1 > sha1(foobar) = 72833f1c7d3b80aadc836d5d035745ffa3a65894
This assumes that the functions in $methods are endomorphisms, so to speak, meaning that they can be composed in arbitrary order. However, in your example, hex2bin(hex2bin($value)) can fail, because the output of hex2bin is not necessarily a hexdecimal value.
Edit regarding your comment: If you’re looking for a composition f_1(f_2(...(f_N($value))...)) that returns $hash, then you can do the following. First define a function which generates all such compositions of a fixed length N:
function recurse_on_methods($methods, $N, $value)
{
if ($N <= 0) {
yield [$value, 'id'];
} else {
foreach ($methods as $method) {
$recurse = recurse_on_methods($methods, $N - 1, $value);
foreach ($recurse as $r) {
yield [$method($r[0]), $method . ' > ' . $r[1]];
}
}
}
}
Then iterate over a desired range of values for N (the length of the composition) and look for your specific hash in the results:
$hash = sha1(md5(sha1(sha1($value))));
echo 'Looking for a composition that yields ' . $hash . "\n";
for ($N = 1; $N <= 5; $N++) {
$results = recurse_on_methods(['md5', 'sha1'], $N, $value);
foreach ($results as $r) {
if ($r[0] == $hash) {
echo $r[1] . '(' . $value . '): ' . $r[0] . "\n";
}
}
}
Output:
Looking for a composition that yields 93fe1beeef1c02a4162d47f387728a8c9e8633fd
sha1 > md5 > sha1 > sha1 > id(foobar): 93fe1beeef1c02a4162d47f387728a8c9e8633fd
how about:
plain:
php > echo base64_encode(md5("a value"));
YTIxM2RmNDA5YzcwNGY2ZWZkOTY4MTEyMDZmODk0ZTI=
fancy:
php > echo array_reduce(['md5','base64_encode'] // add as much as you like
,function($val,$fn){ return $fn($val); }
,"a value");
YTIxM2RmNDA5YzcwNGY2ZWZkOTY4MTEyMDZmODk0ZTI=
EDIT: this is only partially a solution, what remains is creating a array of desired fn-permutation
Related
i have this code that asks for an input, takes that input, compares it with all the values in a database and assigns a number to it.
if(isset($_GET['subreddit']) && empty($_GET['subreddit'])){
?>
<form method="post">
<input type="search" name="subsearch">
</form>
<?php
$sql = "SELECT subname FROM subreddits";
$result = $conn->query($sql);
while($row = $result->fetch_assoc()) {
$a=array();
array_push($a, $row["subname"]);
if(isset($_POST['subsearch'])){
$c=0;
foreach ($a as $value){
$value2 =$_POST['subsearch'];
$sim = similar_text($value, $value2 , $perc);
echo $value." ".$sim. "<br>";
}
}
}
die();}
I want to sort the array $a by the number the similar_text() function outputs.
I'd add it to a new $z array with $sim . '_' . $value . '_' . $index as the key, then sort $z with ksort();.
String values with padded 0's are necessary for sorting because both $sim and $value could have duplicates. The appended $index makes sure the duplicate values aren't lost.
It seems excessive, but 2 foreach loops are required to get the largest string length of $sim for efficiently padding the keys.
end($a);
$aLength = strlen(key($a));
$largestSimLength = 1;
$y = $z = array();
foreach ($a as $value) {
$sim = similar_text($value, $_POST['subsearch'] , $perc);
$simLength = strlen($sim);
$y[] = $sim;
if ($simLength > $largestSimLength) {
$largestSimLength = $simLength;
}
}
foreach ($a as $index => $value) {
$z[str_pad($y[$index], $largestSimLength, '0', STR_PAD_LEFT) . '_' . $value . '_' . str_pad($index, $aLength, '0', STR_PAD_LEFT)] = $value;
}
ksort($z);
print_r($z);
I'm trying to code Conway look-and-say sequence in PHP.
Here is my code:
function look_and_say ($number) {
$arr = str_split($number . " ");
$target = $arr[0];
$count = 0;
$res = "";
foreach($arr as $num){
if($num == $target){
$count++;
}else{
$res .= $count . $target;
$count = 1;
$target = $num;
}
}
return $res;
}
As I run the function, look_and_say(9900) I am getting value I expected: 2920.
My question is for assigning $arr to be $arr = str_split($number) rather than $arr = str_split($number . " "), the result omits the very last element of the $arr and return 29.
Is it normal to add empty space at the end of the $arr foreach to examine the last element or is there any better way to practice this code - besides regex way.
There are 2 methods I was able to come up with.
1 is to add concatenate at the result after the loop too.
function look_and_say ($number) {
$arr = str_split($number);
$target = $arr[0];
$count = 0;
$res = "";
foreach($arr as $num){
if($num == $target){
$count++;
}else{
$res .= $count . $target;
$count = 1;
$target = $num;
}
}
$res .= $count . $target;
return $res;
}
And the 2nd one is to add another if clause inside the loop and determine the last iteration:
function look_and_say ($number) {
$arr = str_split($number);
$target = $arr[0];
$count = 0;
$res = "";
$i=0;
$total = count($arr);
foreach($arr as $num){
if($i == ($total-1))
{
$count++;
$res .= $count . $target;
}
elseif($num == $target){
$count++;
}else{
$res .= $count . $target;
$count = 1;
$target = $num;
}
$i++;
}
return $res;
}
I want to suggest you other way using two nested while loops:
<?php
function lookAndSay($number) {
$digits = str_split($number);
$result = '';
$i = 0;
while ($i < count($digits)) {
$lastDigit = $digits[$i];
$count = 0;
while ($i < count($digits) && $lastDigit === $digits[$i]) {
$i++;
$count++;
}
$result .= $count . $lastDigit;
}
return $result;
}
I'm looking for a travel auto-link detection.
I'm trying to make a social media website and when my users post URLs I need it so like shows instead of just normal text.
Try Autologin for Laravel by dwightwatson, which provides you to generate URLs that will provide automatic login to your application and then redirect to the appropriate location
As far as I know, there's no equivalent in the Laravel's core for the auto_link() funtion helper from Code Igniter (assuming you are refering to the CI version).
Anyway, it's very simple to grab that code and use it in Laravel for a quick an dirty workaround. I just did casually looking for the same issue.
Put in your App directory a container class for your helpers (or any containter for the matter, it's just need to be discovered by the framework), in this case I put a UrlHelpers.php file. Then, inside of it put this two static functions grabbed for the CI version:
class UrlHelpers
{
static function auto_link($str, $type = 'both', $popup = FALSE)
{
// Find and replace any URLs.
if ($type !== 'email' && preg_match_all('#(\w*://|www\.)[^\s()<>;]+\w#i', $str, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
// Set our target HTML if using popup links.
$target = ($popup) ? ' target="_blank"' : '';
// We process the links in reverse order (last -> first) so that
// the returned string offsets from preg_match_all() are not
// moved as we add more HTML.
foreach (array_reverse($matches) as $match) {
// $match[0] is the matched string/link
// $match[1] is either a protocol prefix or 'www.'
//
// With PREG_OFFSET_CAPTURE, both of the above is an array,
// where the actual value is held in [0] and its offset at the [1] index.
$a = '<a href="' . (strpos($match[1][0], '/') ? '' : 'http://') . $match[0][0] . '"' . $target . '>' . $match[0][0] . '</a>';
$str = substr_replace($str, $a, $match[0][1], strlen($match[0][0]));
}
}
// Find and replace any emails.
if ($type !== 'url' && preg_match_all('#([\w\.\-\+]+#[a-z0-9\-]+\.[a-z0-9\-\.]+[^[:punct:]\s])#i', $str, $matches, PREG_OFFSET_CAPTURE)) {
foreach (array_reverse($matches[0]) as $match) {
if (filter_var($match[0], FILTER_VALIDATE_EMAIL) !== FALSE) {
$str = substr_replace($str, static::safe_mailto($match[0]), $match[1], strlen($match[0]));
}
}
}
return $str;
}
static function safe_mailto($email, $title = '', $attributes = '')
{
$title = (string)$title;
if ($title === '') {
$title = $email;
}
$x = str_split('<a href="mailto:', 1);
for ($i = 0, $l = strlen($email); $i < $l; $i++) {
$x[] = '|' . ord($email[$i]);
}
$x[] = '"';
if ($attributes !== '') {
if (is_array($attributes)) {
foreach ($attributes as $key => $val) {
$x[] = ' ' . $key . '="';
for ($i = 0, $l = strlen($val); $i < $l; $i++) {
$x[] = '|' . ord($val[$i]);
}
$x[] = '"';
}
} else {
for ($i = 0, $l = strlen($attributes); $i < $l; $i++) {
$x[] = $attributes[$i];
}
}
}
$x[] = '>';
$temp = array();
for ($i = 0, $l = strlen($title); $i < $l; $i++) {
$ordinal = ord($title[$i]);
if ($ordinal < 128) {
$x[] = '|' . $ordinal;
} else {
if (count($temp) === 0) {
$count = ($ordinal < 224) ? 2 : 3;
}
$temp[] = $ordinal;
if (count($temp) === $count) {
$number = ($count === 3)
? (($temp[0] % 16) * 4096) + (($temp[1] % 64) * 64) + ($temp[2] % 64)
: (($temp[0] % 32) * 64) + ($temp[1] % 64);
$x[] = '|' . $number;
$count = 1;
$temp = array();
}
}
}
$x[] = '<';
$x[] = '/';
$x[] = 'a';
$x[] = '>';
$x = array_reverse($x);
$output = "<script type=\"text/javascript\">\n"
. "\t//<![CDATA[\n"
. "\tvar l=new Array();\n";
for ($i = 0, $c = count($x); $i < $c; $i++) {
$output .= "\tl[" . $i . "] = '" . $x[$i] . "';\n";
}
$output .= "\n\tfor (var i = l.length-1; i >= 0; i=i-1) {\n"
. "\t\tif (l[i].substring(0, 1) === '|') document.write(\"&#\"+unescape(l[i].substring(1))+\";\");\n"
. "\t\telse document.write(unescape(l[i]));\n"
. "\t}\n"
. "\t//]]>\n"
. '</script>';
return $output;
}
}
The function safe_mailto is used in case there are email links in your string. If you don't need it you are free to modify the code.
Then you could use the helper class like this in any part of your Laravel code as usually (here inside a blade template, but the principle is the same):
<p>{!! \App\Helpers\Helpers::auto_link($string) !!}</p>
Quick and dirty, and It works. Hope to have helped. ¡Good luck!
I have a little problem with a script I wrote.
It basically combines permutations of text in every possible order.
For some reason it is adding a space in between every character - can anyone figure out why?
Thanks in advance.
<?php
if(isset($_POST['submit']))
{
//pull in the perms
$perms = "{#A#B#C|#A#B#D|#A#B#E|#A#B#F|#A#C#D|#A#C#E|#A#C#F|#A#D#E|#A#D#F|#A#E#F|#B#C#D|#B#C#E|#B#C#F|#B#D#E|#B#D#F|#B#E#F|#C#D#E|#C#D#F|#C#E#F|#D#E#F}";
//open the box's
$box1= fopen("box1.txt","r");
$box2= fopen("box2.txt","r");
$box3= fopen("box3.txt","r");
$box4= fopen("box4.txt","r");
$box5= fopen("box5.txt","r");
$box6= fopen("box6.txt","r");
//this is the output
$tulis = fopen("output.txt","w+");
//read the box's
$box1 = fread($box1, filesize("box1.txt"));
$box2 = fread($box2, filesize("box2.txt"));
$box3 = fread($box3, filesize("box3.txt"));
$box4 = fread($box4, filesize("box4.txt"));
$box5 = fread($box5, filesize("box5.txt"));
$box6 = fread($box6, filesize("box6.txt"));
$perms = str_replace("#A","$box1",$perms);
$perms = str_replace("#B","$box2",$perms);
$perms = str_replace("#C","$box3",$perms);
$perms = str_replace("#D","$box4",$perms);
$perms = str_replace("#E","$box5",$perms);
$perms = str_replace("#F","$box6",$perms);
echo $text;
fwrite($tulis,$perms);
//close them properly
$box1= fopen("box1.txt","r");
$box2= fopen("box2.txt","r");
$box3= fopen("box3.txt","r");
$box4= fopen("box4.txt","r");
$box5= fopen("box5.txt","r");
$box6= fopen("box6.txt","r");
fclose($box1);
fclose($box2);
fclose($box3);
fclose($box4);
fclose($box5);
fclose($box6);
fclose($tulis);
}
//this means that if the submit button hasn't been pressed, print the form!
else
{
print '
<form action="'.$_SERVER['PHP_SELF'].'" method="POST">
<input type="submit" name="submit"></input>
</form>
';
}
?>
Unless I am mistaking and I missed what you are trying to do, this script is doing pretty much like what you wrote, except that there are no str_replace and it creates permuations automatically for the number of files you provide (at least 3 for it to work properly) :
$files = array(
"box1.txt",
"box2.txt",
"box3.txt",
"box4.txt",
"box5.txt",
"box6.txt"
);
$contents = array();
foreach ($files as $index => $filename) {
$contents[$index] = trim(file_get_contents($filename), " \n\r");
}
$perms = array();
$len = count($contents);
for ($i=0; $i<$len-2; $i++) {
for ($j=$i+1; $j<$len-1; $j++) {
for ($k=$j+1; $k<$len; $k++) {
$perms[] = $contents[$i] . $contents[$j] . $contents[$k];
}
}
}
$text = '{' . implode('|', $perms) . '}';
file_put_contents('output.txt', $text);
Note that this version does not use fopen and trim the text read from the files to remove any whitespaces (CR and CL characters too) from the content.
** Edit **
This is the actual test program that I have made :
header('Content-type: text/plain; charset=utf-8');
$contents = array(
'A', 'B', 'C', 'D', 'E', 'F'
);
// fixed embedded loops method
$perms = array();
$len = count($contents);
for ($i=0; $i<$len-2; $i++) {
for ($j=$i+1; $j<$len-1; $j++) {
for ($k=$j+1; $k<$len; $k++) {
$perms[] = $contents[$i] . $contents[$j] . $contents[$k];
}
}
}
$text = '{' . implode('|', $perms) . '}';
echo $text . "\n";
// Recursive method
function permutationRecursive( & $perms, $maxDepth, $contents = array(), $values = array(), $startIndex = 0) {
for ($i=$startIndex, $count=count($contents)-($maxDepth-1); $i<$count; $i++) {
array_push($values, $contents[$i]);
if ($maxDepth > 1) {
permutationRecursive( $perms, $maxDepth - 1, $contents, $values, $i + 1);
} else {
$perms[] = implode($values);
}
array_pop($values);
}
}
$perms = array();
permutationRecursive($perms, 3, $contents);
$text = '{' . implode('|', $perms) . '}';
echo $text . "\n";;
The output of this script is
{ABC|ABD|ABE|ABF|ACD|ACE|ACF|ADE|ADF|AEF|BCD|BCE|BCF|BDE|BDF|BEF|CDE|CDF|CEF|DEF}
{ABC|ABD|ABE|ABF|ACD|ACE|ACF|ADE|ADF|AEF|BCD|BCE|BCF|BDE|BDF|BEF|CDE|CDF|CEF|DEF}
I want to give our users in the database a unique alpha-numeric id. I am using the code below, will this always generate a unique id? Below is the updated version of the code:
old php:
// Generate Guid
function NewGuid() {
$s = strtoupper(md5(uniqid(rand(),true)));
$guidText =
substr($s,0,8) . '-' .
substr($s,8,4) . '-' .
substr($s,12,4). '-' .
substr($s,16,4). '-' .
substr($s,20);
return $guidText;
}
// End Generate Guid
$Guid = NewGuid();
echo $Guid;
echo "<br><br><br>";
New PHP:
// Generate Guid
function NewGuid() {
$s = strtoupper(uniqid("something",true));
$guidText =
substr($s,0,8) . '-' .
substr($s,8,4) . '-' .
substr($s,12,4). '-' .
substr($s,16,4). '-' .
substr($s,20);
return $guidText;
}
// End Generate Guid
$Guid = NewGuid();
echo $Guid;
echo "<br><br><br>";
Will the second (new php) code guarantee 100% uniqueness.
Final code:
PHP
// Generate Guid
function NewGuid() {
$s = strtoupper(uniqid(rand(),true));
$guidText =
substr($s,0,8) . '-' .
substr($s,8,4) . '-' .
substr($s,12,4). '-' .
substr($s,16,4). '-' .
substr($s,20);
return $guidText;
}
// End Generate Guid
$Guid = NewGuid();
echo $Guid;
$alphabet = '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ';
function base_encode($num, $alphabet) {
$base_count = strlen($alphabet);
$encoded = '';
while ($num >= $base_count) {
$div = $num/$base_count;
$mod = ($num-($base_count*intval($div)));
$encoded = $alphabet[$mod] . $encoded;
$num = intval($div);
}
if ($num) $encoded = $alphabet[$num] . $encoded;
return $encoded;
}
function base_decode($num, $alphabet) {
$decoded = 0;
$multi = 1;
while (strlen($num) > 0) {
$digit = $num[strlen($num)-1];
$decoded += $multi * strpos($alphabet, $digit);
$multi = $multi * strlen($alphabet);
$num = substr($num, 0, -1);
}
return $decoded;
}
echo base_encode($Guid, $alphabet);
}
So for more stronger uniqueness, i am using the $Guid as the key generator. That should be ok right?
If you want the id to be unique, you should generate a GUID using uniqid.
Your method will not guarantee uniqueness at all. And will likely create collisions.
The code below will generate you a unique alpha-numeric ID from a number. I took it from Flickr groups. Two functions to encode and decode:
$alphabet = '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ';
function base_encode($num, $alphabet) {
$base_count = strlen($alphabet);
$encoded = '';
while ($num >= $base_count) {
$div = $num/$base_count;
$mod = ($num-($base_count*intval($div)));
$encoded = $alphabet[$mod] . $encoded;
$num = intval($div);
}
if ($num) $encoded = $alphabet[$num] . $encoded;
return $encoded;
}
function base_decode($num, $alphabet) {
$decoded = 0;
$multi = 1;
while (strlen($num) > 0) {
$digit = $num[strlen($num)-1];
$decoded += $multi * strpos($alphabet, $digit);
$multi = $multi * strlen($alphabet);
$num = substr($num, 0, -1);
}
return $decoded;
}
UPDATE
Usage:
echo base_encode(123456789, $alphabet); //should output: bUKpk
uniqid: <?php $substr = substr(md5(rand()),0,22);echo " $substr ";?>
If it's truly random, then you can not guarantee uniqueness (unless you keep generating random keys and checking them against your database until you find a new one, which is a horrible idea).
Does it really need to be random?
Why not just use an autoincrement column in the table, and then convert it to base-62 (or so) if you want to reference it as an alphanumeric value?