how to generate a random base64 number to power of 11 - php

im trying to work on urls, so i need a random base64 to the power of 11 number, which changes every time you refresh the page.
Im working in php.
any help would be great,
many thanks.
not sure how to go about but maybe somthing like bellow?
function toChars($number) {
$res = base_convert($number, 10,26);
$res = strtr($res,'0123456789','qrstuvxwyz');
return $res;
}
or
$res = ('0123456789','abcdefghijklmnopqrstuvxwyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
then randomly select from that till you get a 11 digit number aka(base64 to power of 11)
and echo the number here $random_base64_number = ?

Dont worry figured it out.
function base62() {
$index = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_';
$res = '';
for ($x = 1; $x <= 11; $x++) {
$res .= $index[rand(1, strlen($index))];
}
echo "The number is: $res <br>";
}

Related

Convert a search query into 1's and 0's and use as a variable

Hello everyone and thanks for the time you will spend on this question.
Problem
I am trying to convert my search query into 1's and 0's to check for a match inside my database.
Basically, I fill my form input with this query: SF12345
The code checks for each chars if it's numeric. If it is, it outputs a 1 if not it outputs a 0. So my code (SO's code :) ) so far will output 0011111. So far, so good:
$s = "SF12345";
for ($i = 0; $i < strlen($s); $i++){
$char = $s[$i];
if (is_numeric($char)) {
echo "1";
} else {
echo "0";
}
}
Question
How do I "implode" or "regroup" all these echo's to use as one variable inside my search query below
$dbConn->query("SELECT * FROM products WHERE code = '".$s.'");
I want it to look like this
$dbConn->query("SELECT * FROM products WHERE code = '0011111'");
If anyone has any idea on how to approach or solve this issue, you'll make one (very) happy man.
If it is important to know why I want to convert it to 1's and 0's I'll be glad to explain.
Thank you very much, all help is much appreciated.
You could append to a string in PHP with the concatenating assignment operator .=. (See https://www.php.net/manual/en/language.operators.string.php for more information). Then you could do this:
$s = "SF12345";
$output = ""; // This will store the result.
for ($i = 0;$i < strlen($s);$i++)
{
$char = $s[$i];
if (is_numeric($char))
{
$output .= "1";
}
else
{
$output .= "0";
}
}

Is there a faster way than array_diff in PHP

I have a set of numbers from MySQL within the range 1000 0000 (8 digits) to 9 999 999 999 (10 digits). It's supposed to be consecutive, but there are missing numbers. I need to know which numbers are missing.
The range is huge. At first I was going to use PHP to do this:
//MySqli Select Query
$results = $mysqli->query("SELECT `OCLC Number` FROM `MARC Records by Number`");
$n_array = array();
while($row = $results->fetch_assoc()) {
$n_array[] = $row["OCLC Number"];
}
d($n_array);
foreach($n_array as $k => $val) {
print $val . " ";
}
/* 8 digits */
$counter = 10000000;
$master_array = array();
/* 10 digits */
while ($counter <= 9999999999 ) {
$master_array[] = $counter;
$counter++;
d($master_array);
}
d($master_array);
$missing_numbers_ar = array_diff ($master_array, $n_array);
d($missing_numbers_ar);
d() is a custom function akin to var_dump().
However, I just realized it would take tons of time for this to be done. At the 15 minute mark, $master_array is being populated with only 4000 numbers.
How can I do this in a quicker way? MySQL-only or MySQL-and-PHP solutions both welcome. If the optimal solution depends on how many numbers are missing, please let me know how so. Tq.
Your d() probably is the cause of slowness, please remove it, and make small changes in your code
while($row = $results->fetch_assoc()) {
$n_array[$row["OCLC Number"]] = 1;
}
and
$missing_numbers_ar = [];
while ($counter++ <= 9999999999 ) {
if (empty($n_array[$counter])) {
$missing_numbers_ar[] = $counter;
}
}
If the following is still slow I would be surprised. I also just noticed it is similar to #Hieu Vo's answer.
// Make sure the data is returned in order by adding
// an `ORDER BY ...` clause.
$results = $mysqli->query("SELECT `OCLC Number`
FROM `MARC Records by Number`
ORDER BY `OCLC Number`");
$n_array = array();
while($row = $results->fetch_assoc()) {
// Add the "OCLC Number" as a key to the array.
$n_array[$row["OCLC Number"]] = $row["OCLC Number"];
}
// assume the first array key is in fact correct
$i = key($n_array);
// get the last key, also assume it is not missing.
end($n_array);
$max = key($n_array);
// reset the array (should not be needed)
reset($n_array);
do {
if (! $n_array[$i]) {
echo 'Missing key:['.$i.']<br />';
// flush the data to the page as you go.
flush();
}
} while(++$i <= $max);

Random generator returning endless duplicates

I am trying to create a random string which will be used as a short reference number. I have spent the last couple of days trying to get this to work but it seems to get to around 32766 records and then it continues with endless duplicates. I need at minimum 200,000 variations.
The code below is a very simple mockup to explain what happens. The code should be syntaxed according to 1a-x1y2z (example) which should give a lot more results than 32k
I have a feeling it may be related to memory but not sure. Any ideas?
<?php
function createReference() {
$num = rand(1, 9);
$alpha = substr(str_shuffle("abcdefghijklmnopqrstuvwxyz"), 0, 1);
$char = '0123456789abcdefghijklmnopqrstuvwxyz';
$charLength = strlen($char);
$rand = '';
for ($i = 0; $i < 6; $i++) {
$rand .= $char[rand(0, $charLength - 1)];
}
return $num . $alpha . "-" . $rand;
}
$codes = [];
for ($i = 1; $i <= 200000; $i++) {
$code = createReference();
while (in_array($code, $codes) == true) {
echo 'Duplicate: ' . $code . '<br />';
$code = createReference();
}
$codes[] = $code;
echo $i . ": " . $code . "<br />";
}
exit;
?>
UPDATE
So I am beginning to wonder if this is not something with our WAMP setup (Bitnami) as our local machine gets to exactly 1024 records before it starts duplicating. By removing 1 character from the string above (instead of 6 in the for loop I make it 5) it gets to exactly 32768 records.
I uploaded the script to our centos server and had no duplicates.
What in our enviroment could cause such a behaviour?
The code looks overly complex to me. Let's assume for the moment you really want to create n unique strings each based on a single random value (rand/mt_rand/something between INT_MIN,INT_MAX).
You can start by decoupling the generation of the random values from the encoding (there seems to be nothing in the code that makes a string dependant on any previous state - excpt for the uniqueness). Comparing integers is quite a bit faster than comparing arbitrary strings.
mt_rand() returns anything between INT_MIN and INT_MAX, using 32bit integers (could be 64bit as well, depends on how php has been compiled) that gives ~232 elements. You want to pick 200k, let's make it 400k, that's ~ a 1/10000 of the value range. It's therefore reasonable to assume everything goes well with the uniqueness...and then check at a later time. and add more values if a collision occured. Again much faster than checking in_array in each iteration of the loop.
Once you have enough values, you can encode/convert them to a format you wish. I don't know whether the <digit><character>-<something> format is mandatory but assume it is not -> base_convert()
<?php
function unqiueRandomValues($n) {
$values = array();
while( count($values) < $n ) {
for($i=count($values);$i<$n; $i++) {
$values[] = mt_rand();
}
$values = array_unique($values);
}
return $values;
}
function createReferences($n) {
return array_map(
function($e) {
return base_convert($e, 10, 36);
},
unqiueRandomValues($n)
);
}
$start = microtime(true);
$references = createReferences(400000);
$end = microtime(true);
echo count($references), ' ', count(array_unique($references)), ' ', $end-$start, ' ', $references[0];
prints e.g. 400000 400000 3.3981630802155 f3plox on my i7-4770. (The $end-$start part is constantly between 3.2 and 3.4)
Using base_convert() there can be strings like li10, which can be quite annoying to decipher if you have to manually type the string.

Numbers to letters with logical sequence

I have this array which links numbers to letters at the moment like this:
1-26 = A-Z
But there is more, 27=AA and 28=AB etc...
so basically when I do this:
var_dump($array[2]); //shows B
var_dump($array[29]); //shows AC
Now this array I made myself but it's becoming way too long. Is there a way to actually get this going on till lets say 32? I know there is chr but I dont think I can use this.
Is there an easier way to actually get this without using this way too long of an array?
It's slower calculating it this way, but you can take advantage of the fact that PHP lets you increment letters in the same way as numbers, Perl style:
function excelColumnRange($number) {
$character = 'A';
while ($number > 1) {
++$character;
--$number;
}
return $character;
}
var_dump(excelColumnRange(2));
var_dump(excelColumnRange(29));
here is the code which you are looking for :
<?php
$start = "A";
$max = 50;
$result = array();
for($i=1; $i<=$max; $i++) {
$result[$i] = $start++;
}
print_r($result);
?>
Ref: http://www.xpertdeveloper.com/2011/01/php-strings-unusual-behaviour/
This should work for you:
Even without any loops. First I calculate how many times the alphabet (26) goes into the number. With this I define how many times it has to str_repleat() A. Then I simply subtract this number and calculate the number in the alphabet with the number which is left.
<?php
function numberToLetter($number) {
$fullSets = (($num = floor(($number-1) / 26)) < 0 ? 0 : $num);
return str_repeat("A", $fullSets) . (($v = ($number-$fullSets*26)) > 0 ? chr($v+64) : "");
}
echo numberToLetter(53);
?>
output:
AAA

PHP Pagination - detect current page

What is the best way to detect/print the current page number (pagination)?
I tried two different ways, and now i want to know if there exists a better way to do it.
I:
$number = 12; //current page number
$all = 40; // all pages
$range = 4; // number of pages shown (up and down)
$min = $number-$range;
$max= $number+$range+1;
for($i=$min; $i<$number;$i++) {
echo "<a href='#'>$i</a><br/>";
}
echo "$number<br/>";
for($i=($number+1); $i<$max;$i++) {
echo "<a href='#'>$i</a></br>";
}
II:
$number = 12; //current page number
$all = 40; // all pages
$range = 4; // number of pages shown (up and down)
$min = $number-$range;
$max= $number+$range+1;
for($i=$min; $i<$max;$i++) {
if($i!=$number) {
echo "<a href='#'>$i</a><br/>";
} else {
echo "$i<br/>";
}
}
I also checked the speed of both solutions (using different high-number $all values) and first one is faster in most cases.
Thanks for suggestions :)
Here's a functional alternative (for 0 to 10 pages; replace it with $min $number-1 .. )
echo implode("<br/>",
array_map(function($x){
return "<a href='..'>$x</a>";
}, range(0,10))
);
Please time it, and let me know. :)

Categories