Alphanumeric string increment using for loop - php

I have a two variable one is string contains number and another one is number,
I want increase the numeric part of string upto second number.
$n ='sh500';
$c = 3;
for($i=$n;$i<$c;$i++)
echo $i.'<br>';
I want output like:
sh500
sh501
sh502

Use $n++ where $n = 'sh500'. It works.
$n ='sh500';
$c = 3;
for($i = 0;$i < $c;$i++) {
echo $n++.'<br>';
}
Will output
sh500 <br>
sh501 <br>
sh502 <br>
It even works when ending with a alphanumeric character, because php converts it to the ASCII value of the character and adds one so a will become b and so on. But that's out of the scope of the question :)

$x="sh500";
$x = substr($x,0,2) . (substr($x,2) + 1);
echo $x;
echoes sh501 (works for any string having a number from 3rd character)

$n = 'sh';
for($i = 500; $i < 503; $i++) {
echo "$n$i\n";
}

$n="sh50";
for($i=0;$i<10;$i++){
$j=$n.$i;
echo $j."<br>";
}
it echo:
sh500
sh501
sh502
sh503
sh504
sh505
sh506
sh507
sh508
sh509

$n = 'sh500';
$c = 3;
$sh = substr($n,0,2); // will be "sh"
$number = substr($n,2,5) + 1; // will be "500"
for($i = $number; $i < 504; $i++) {
echo $sh.$i."\n";
}
Live demo: Here

if it is always a string of length 2 else use preg_match to find the first occurrence of a number.
http://www.php.net/manual/en/function.preg-match.php
$number = intval(substr($n, 2));
$number++;
echo substr($n, 0, 2) . $number;

$x = "sh500";
$s = substr($x, 0, 2);
$n = substr($x, 2);
$c = 3;
for ($i = $n; $i < ($n + $c); $i++)
{
echo $s.$i.'<br>';
}
OR another simple way is...
$n ='sh500';
$c = 3;
for ($i = 0; $i < $c; $i++) {
echo $n++."<br>";
}
Output
sh500
sh501
sh502

Related

Why can't I use a function to simplify my "for loops"

I build a webpage to crack simple MD5 hash of a four digit pin for fun. The method I used was basically try all combination and check against the MD5 value the user has entered. Below is the PHP code I created to accomplish the goal.
Debug Output:
<?php
$answer = "PIN not found";
if (isset($_GET['md5'])) {
$txt = 'abcdefjhig';
$time_pre = microtime(TRUE);
$value = $_GET['md5'];
$show = 15;
for ($i = 0; $i <= 9; $i++) {
$first = $i;
for ($j = 0; $j <= 9; $j++) {
$second = $j;
for ($k = 0; $k <= 9; $k++) {
$third = $k;
for ($x = 0; $x <= 9; $x++) {
$fourth = $x;
$whole = $first . $second . $third . $fourth;
$check = hash('md5', $whole);
if ($check == $value) {
$answer = $whole;
echo "The pin is $answer";
}
if ($show > 0) {
print"$check $whole \n";
$show = $show - 1;
}
}
}
}
}
echo "\n";
$time_post = microtime(TRUE);
print "Elapsed time:";
print $time_post - $time_pre;
}
?>
Notice that in the middle there are four very similar for loops,I tried to simplify this by using functions, but it just returns one four digit number which is 9999 instead of all of them.
Below is the function I created:
function construct($input){
for($i=0; $i<=9, $i++){
$input=$i;
}
return $input
}
Then I tried to call this function for four times to form all of the four digit numbers but it just gives me 9999. Can anybody help? Thanks a lot.
Try this:
for ($i=0; $i<=9999 ; $i++) {
$whole = sprintf('%04d', $i);
$check=hash('md5', $whole);
if($check==$value){
$answer=$whole;
echo "The pin is $answer";
break; //remove this if you do not want to break the loop here
}
if ($show>0) {
print"$check $whole \n";
$show=$show-1;
}
}
You're using numbers from 0 to 9999, so why just loop through those numbers? You can add zero's by using str_pad() like so:
for ($i = 0; $i <= 9999; $i++) {
$whole = str_pad($i, 4, '0', STR_PAD_LEFT);
}
Also I'd like to mention that you really should think about better formatting of your code, especially indentation

How to replace multiple random characters in string with underscore(_) in PHP

I am using codes like "gjhyYhK", "HJjhkeuJ" etc. But want user to show these codes like:
gj_y__K
HJj__e_J
means code will be edited with "_" at random positions in code.
This will do what you want:
$str = "gjhyYhK";
$len = strlen($str);
$num_to_remove = ceil($len * .4); // 40% removal
for($i = 0; $i < $num_to_remove; $i++)
{
$k = 0;
do
{
$k = rand(1, $len);
} while($str[$k-1] == "_");
$str[$k-1] = "_";
}
print $str . "\n";
If you want more underscores, change the value of $underscores. This will guarantee you get how many underscores you want, so long as you want fewer than the length of the string
Try this:
$string=array(
'gjhyYhK',
'HJjhkeuJ'
);
$arr=array();
foreach ($string as $key=>$value) {
$arr[$key]='';
for ($i=1; $i <=strlen($value); $i++) {
if(rand(0,1)){
$arr[$key].=substr($string[$key],$i,1);
}else{
$arr[$key].='_';
}
}
}
var_dump($arr);
you can try below code to get the functionality what you are looking for
<?php
$string = "gjhyYhK";
$percentage = 40;
$total_length = strlen($string);
$number_of_underscore = floor(($percentage / 100) * $total_length); // I have use floor value, you can use ceil() as well
for ($i = 1; $i <= $number_of_underscore; $i++)
{
$random_position = rand(0, strlen($string) - 1); // get the random position of character to be replaced
if (substr($string, $random_position, 1) !== '_') // check if its already replaced underscore (_)
{
$string = preg_replace("/" . (substr($string, $random_position, 1)) . "/", '_', $string, 1); // here preg_replaced use to replace the character only once, (i.e str_replace() will replace all matching characters)
}
else
{
$i--; // else decrement $i for the loop to run one more time
}
}
echo $string;
?>
let me know if any other help needed
$str = "ADFJ";
$strlen = strlen($str);
$newStr = '';
for ($i = 0; $i < $strlen; $i++) {
if ($i == rand(0, $strlen)) {
$newStr .= '_';
} else {
$newStr .= $str[$i];
}
}
echo $newStr;

defining alphabets as numbers not working inside loop

Please check my code below,it returns 0 while I am expecting a result 14.But when I add A+D manually it returns 5.Am i doing something wrong inside the loop ?
<?php
define('A',1);
define('B',2);
define('C',3);
define('D',4);
define('E',5);
//echo A+D; returns 5
$name = 'EACE';
$len = strlen($name);
for($i = 0; $i<=$len; $i++)
{
$val += $name[$i];
}
echo $val; //returns 0
?>
You need to use constant(..) to get the value of a constant by name. Try this:
for ($i = 0; $i < strlen($name); $i++) {
$val += constant($name[$i]);
}
define('A',1);
define('B',2);
define('C',3);
define('D',4);
define('E',5);
//echo A+D; returns 5
$name = 'EACE';
$len = strlen($name);
$val = null;
for($i = 0; $i<=$len-1; $i++)
{
$val += constant($name[$i]);
}
echo $val;

PHP - Efficiency while searching for palindrome

I was challenged by a friend to code some PHP to find the longest palindrome in provided text, my solution is below, how could I make it more efficient?
$string = file_get_contents("http://challenge.greplin.com/static/gettysburg.txt");
echo $string;
function isPalendrone($string) {
if ($string == strrev($string))
return true;
else
return false;
}
$longest = "";
for($i = 0; $i < strlen($string)-1; $i++) {
$afterCurrent = substr($string, $i);
for($j = 0; $j < strlen($afterCurrent)-1; $j++) {
$section = substr($afterCurrent, 0, $j);
if(isPalendrone($section)) {
if(strlen($longest)<strlen($section)) {
$longest = $section;
}
}
}
}
echo "<br /><br/>The longest was: ".$longest."<br /> which is ".strlen($longest)." chars long";
This reverses the entire string and just does substr() matches against each:
$rev = strrev($txt);
$len = strlen($txt);
$longest_len = 0;
$longest_str = null;
for ($i = 0; $i < $len; ++$i)
{
for ($j = $len - $i; $j > $longest_len; --$j)
{
if (substr($txt, $i, $j) == substr($rev, $len-$i-$j, $j))
{
$longest_len = $j;
$longest_str = substr($txt, $i, $j);
break;
}
}
}
I didn't try to optimize the implementation. e.g., It might be a little faster to skip the substr and do a char-by-char approach, because you could break out faster. In that case, you wouldn't really even need to reverse the string.
To get the longest palindrome - you have to start with longest string (not with shortest like you do now), check it and break on first match.
Also you'd better just keep 2 pointers ($i and $j) and not perform substr twice. It is enough to have i and j and substr once, right before you perform if(isPalendrone()) condition.
My implementation (~20% faster than yours):
<?php
$string = 'FourscoreandsevenyearsagoourfaathersbroughtforthonthiscontainentanewnationconceivedinzLibertyanddedicatedtothepropositionthatallmenarecreatedequalNowweareengagedinagreahtcivilwartestingwhetherthatnaptionoranynartionsoconceivedandsodedicatedcanlongendureWeareqmetonagreatbattlefiemldoftzhatwarWehavecometodedicpateaportionofthatfieldasafinalrestingplaceforthosewhoheregavetheirlivesthatthatnationmightliveItisaltogetherfangandproperthatweshoulddothisButinalargersensewecannotdedicatewecannotconsecratewecannothallowthisgroundThebravelmenlivinganddeadwhostruggledherehaveconsecrateditfaraboveourpoorponwertoaddordetractTgheworldadswfilllittlenotlenorlongrememberwhatwesayherebutitcanneverforgetwhattheydidhereItisforusthelivingrathertobededicatedheretotheulnfinishedworkwhichtheywhofoughtherehavethusfarsonoblyadvancedItisratherforustobeherededicatedtothegreattdafskremainingbeforeusthatfromthesehonoreddeadwetakeincreaseddevotiontothatcauseforwhichtheygavethelastpfullmeasureofdevotionthatweherehighlyresolvethatthesedeadshallnothavediedinvainthatthisnationunsderGodshallhaveanewbirthoffreedomandthatgovernmentofthepeoplebythepeopleforthepeopleshallnotperishfromtheearth';
function isPalendrone($string) {
return $string == strrev($string);
}
$longest = '';
$length = strlen($string);
for ($i = 0; $i < $length - 1; $i++) {
for ($j = $length - $i; $j > 1; $j--) {
if (isPalendrone(substr($string, $i, $j))) {
$new = substr($string, $i, $j);
if (strlen($new) > strlen($longest)) $longest = $new;
break;
}
}
}
echo "<br /><br/>The longest was: ".$longest."<br /> which is ".strlen($longest)." chars long";

Auto incrementing unique url

I am looking to create an auto incrementing unique string using PHP, containing [a-Z 0-9] starting at 2 chars long and growing when needed.
This is for a url shrinker so each string (or alias) will be saved in the database attached to a url.
Any insight would be greatly appreciated!
Note this solution won't produce uppercase letters.
Use base_convert() to convert to base 36, which will use [a-z0-9].
<?php
// outputs a, b, c, ..., 2o, 2p, 2q
for ($i = 10; $i < 99; ++$i)
echo base_convert($i, 10, 36), "\n";
Given the last used number, you can convert it back to an integer with intval() increment it and convert the result back to base 36 with base_convert().
<?php
$value = 'bc9z';
$value = intval($value, 36);
++$value;
$value = base_convert($value, 10, 36);
echo $value; // bca0
// or
echo $value = base_convert(intval($value, 36) + 1, 10, 36);
Here's an implementation of an incr function which takes a string containing characters [0-9a-zA-Z] and increments it, pushing a 0 onto the front if required using the 'carry-the-one' method.
<?php
function incr($num) {
$chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$parts = str_split((string)$num);
$carry = 1;
for ($i = count($parts) - 1; $i >= 0 && $carry; --$i) {
$value = strpos($chars, $parts[$i]) + 1;
if ($value >= strlen($chars)) {
$value = 0;
$carry = 1;
} else {
$carry = 0;
}
$parts[$i] = $chars[$value];
}
if ($carry)
array_unshift($parts, $chars[0]);
return implode($parts);
}
$num = '0';
for ($i = 0; $i < 1000; ++$i) {
echo $num = incr($num), "\n";
}
If your string was single case rather than mixed, and didn't contain numerics, then you could literally just increment it:
$testString="AA";
for($x = 0; $x < 65536; $x++) {
echo $testString++.'<br />';
}
$testString="aa";
for($x = 0; $x < 65536; $x++) {
echo $testString++.'<br />';
}
But you could possibly make some use of this feature even with a mixed alphanumeric string
To expand on meagar's answer, here is how you can do it with uppercase letters as well and for number arbitrarily big (requires the bcmath extension, but you could as well use gmp or the bigintegers pear package):
function base10ToBase62($number) {
static $chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
$result = "";
$n = $number;
do {
$remainder = bcmod($n, 62);
$n = bcdiv($n, 62);
$result = $chars[$remainder] . $result;
} while ($n > 0);
return $result;
}
for ($i = 10; $i < 99; ++$i) {
echo base10ToBase62((string) $i), "\n";
}

Categories