I want to convert MSB to LSB.
Input Data = 764491139 (MSB) , Correct result = 2201325869 (LSB)
My coding :
$value = "764491139";
echo bindec(strrev(decbin($value))); //Convert to LSB
Result : 812327533; //Correct is 2201325869
but result is incorrect.
Could you help me?
A simple search in Google founds this snippet from the PHP manual
function uInt64($i, $endianness=false) {
$f = is_int($i) ? "pack" : "unpack";
if ($endianness === true) { // big-endian
$i = $f("J", $i);
}
else if ($endianness === false) { // little-endian
$i = $f("P", $i);
}
else if ($endianness === null) { // machine byte order
$i = $f("Q", $i);
}
return is_array($i) ? $i[1] : $i;
}
http://php.net/manual/en/function.unpack.php#119403
Related
Need to write a code block which check is one string is a rotation of another.
Looked at loads of posts on here and it is all in Java or C++ but I need to do it in PHP.
I have tried a few different things, trying to work from the C++ and Java examples but I am not having any luck, here is my current code:
<?php
function isSubstring($s1, $s2) {
if(strlen($s1) != strlen($s2)) {
return false;
}
if(WHAT TO PUT HERE) {
echo "it is!";
} else {
echo "nope";
}
}
isSubstring("hello", "helol");
?>
Many ways available. Here one more using built-in function count_chars on both strings, and then comparing both resulting arrays :
function isSubstring($s1, $s2) {
if (strlen($s1) != strlen($s2)) {
echo "nope";
return;
}
$s1cnt = count_chars($s1, 1);
$s2cnt = count_chars($s2, 1);
if($s1cnt === $s2cnt) {
echo "it is!";
} else {
echo "nope";
}
}
Edit : as MonkeyZeus pointed out, beware of comparison with multibyte characters. It may bite a little bit :
isSubstring('crढap', 'paࢤrc');
will give true as answer. ढ is UTF-8 indian devanagari three byte char : E0 A2 A4 and ࢤ is also three byte chars (arabic) : E0 A4 A2, and the count_chars function counts the individual bytes. So it would be safe to use if chars are from only one language, else get some headache pills...
It seems to me that to manage this kind of things we need to have chars that are made of 3 bytes.
I would go for something like this:
function isSubstring($s1, $s2)
{
// If the strings match exactly then no need to proceed
if($s1 === $s2)
{
echo "it is!";
return;
}
elseif(strlen($s1) !== strlen($s2))
{
// Strings must be of equal length or else no need to proceed
echo "nope";
return;
}
// Put each character into an array
$s1 = str_split($s1);
$s2 = str_split($s2);
// Sort alphabetically based on value
sort($s1);
sort($s2);
// Triple check the arrays against one-another
if($s1 === $s2)
{
echo "it is!";
}
else
{
echo "nope";
}
}
Here is a multibyte safe function to compare the two strings:
function mb_isAnagram($s1, $s2) {
if (strlen($s1) != strlen($s2)) {
return false;
} else {
$c1 = preg_split('//u', $s1, null, PREG_SPLIT_NO_EMPTY);
$c2 = preg_split('//u', $s2, null, PREG_SPLIT_NO_EMPTY);
sort($c1);
sort($c2);
if ($c1 === $c2) {
return true;
} else {
return false;
}
}
}
You could split each string and sort it, like this:
$split1 = unpack("C*",$s1);
asort($split1);
Then you can traverse both arrays comparing the values.
<?php
function isRotationalString($str1,$str2){
$len = strlen($str1);
if($str1 === $str2){
return true;
}else{
if($len == strlen($str2)){
$flag = true;
for($i=0;$i<$len;$i++){
if($str1[0]==$str2[$i]){
$tst = $i;$start = true;break;
}
}
if($start){
for($j=0;$j<$len;$j++){
$m = $j+$tst;
if($m < $len){
if($str1[$j] != $str2[$m]){
$flag = false;break;
}
}else{
if($m>=$len)
{
$k = $m - $len;
if($str1[$j] != $str2[$k]){
$flag = false;break;
}
}
}
}
}else{
$flag = false;
}
return $flag;
}
}
}
echo isRotationalString("abcd","bcda")?'It is':'It is not';
?>
above script will check whether a string is a rotation of another string or not?
isRotationalString("abcd","bcda") => It is
isRotationalString("abcd","cbda") => It is Not
This is the function for string rotation.
echo isRotationalString("abcdef","efabcd")?'It is':'It is not';
function isRotationalString($str1,$str2){
$len = strlen($str1);
if($str1 === $str2){
return true;
} else {
if($len == strlen($str2)) {
$stringMatchedArr1 = $stringMatchedArr2 = [];
for($i=0; $i<$len; $i++) {
$substr = substr($str1,$i );
$pos = strpos($str2, $substr);
if($pos !== false) {
$stringMatchedArr1[] = $substr;
}
}
for($j=1; $j <= $len; $j++) {
$substr = substr($str1, 0, $j );
$pos = strpos($str2, $substr);
if($pos !== false) {
$stringMatchedArr2[] = $substr;
}
}
foreach($stringMatchedArr2 as $string1) {
foreach($stringMatchedArr1 as $string2) {
if($string1.$string2 == $str1)
return true;
}
}
}
}
}
I would sort the characters in the strings by making it an array and then imploding them to a string again.
if (sort(str_split($s1)) == sort(str_split($s2))) {
That would do the trick in one line.
Edit: Thanks Don't Panic, edited my answer!
How can generate a round number according to a number in PHP?
Ex: if my number is
235112, then I should get 300000 or
122432, then I should get 200000 or
328522, then I should get 400000 ?
You can use a helper function to have the round-up:
function roundup ($value, $places=0) {
if ($places < 0)
{
$places = 0;
}
$mult = pow(10, $places);
return ceil($mult*$value)/$mult;
}
and use it like roundup($value,-5); to roundup 5 digits
String approach :
$s as string input
$s = ($s[0] === '9' ? '1' . str_repeat('0', strlen($s)) : (((int)$s[0]) + 1) . str_repeat('0', strlen($s) - 1));
modified version of Gardax answer:
<?php
$str = "328522";
function ceiling($number)
{
$strlen = strlen($number);
$significance = "1";
for($i=0; $i<($strlen-1);$i++)
{
$significance .= "0";
}
return ( is_numeric($number) && is_numeric($significance) ) ? (ceil($number/$significance)*$significance) : false;
}
echo ceiling($str);
?>
I am trying to follow the instructions required to turn a 65 byte public key into a bitcoin address using php. The instructions are quite explicit. Can anyone help me with the practicality of doing that in php?
Instructions are
1 - Take the corresponding public key generated with it (65 bytes, 1 byte 0x04, 32 bytes corresponding to X coordinate, 32 bytes corresponding to Y coordinate)
0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6
2 - Perform SHA-256 hashing on the public key
600FFE422B4E00731A59557A5CCA46CC183944191006324A447BDB2D98D4B408
3 - Perform RIPEMD-160 hashing on the result of SHA-256
010966776006953D5567439E5E39F86A0D273BEE
4 - Add version byte in front of RIPEMD-160 hash (0x00 for Main Network)
00010966776006953D5567439E5E39F86A0D273BEE
5 - Perform SHA-256 hash on the extended RIPEMD-160 result
445C7A8007A93D8733188288BB320A8FE2DEBD2AE1B47F0F50BC10BAE845C094
6 - Perform SHA-256 hash on the result of the previous SHA-256 hash
D61967F63C7DD183914A4AE452C9F6AD5D462CE3D277798075B107615C1A8A30
7 - Take the first 4 bytes of the second SHA-256 hash. This is the address checksum
D61967F6
8 - Add the 4 checksum bytes from point 7 at the end of extended RIPEMD-160 hash from point 4. This is the 25-byte binary Bitcoin Address.
00010966776006953D5567439E5E39F86A0D273BEED61967F6
9 - Convert the result from a byte string into a base58 string using Base58Check encoding. This is the most commonly used Bitcoin Address format
16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM
My first attempt is
// step 1
$publickey='0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6';
$step1=$publickey;
echo "step1 ".$publickey."<br>";
// step 2
$step2=hash("sha256",$step1);
echo "step2 ".$step2."<br>";
// step 3
$step3=hash('ripemd160',$step2);
echo "step3 ".$step3."<br>";
// step 4
$step4="00".$step3;
echo "step4 ".$step4."<br>";
// step 5
$step5=hash("sha256",$step4);
echo "step5 ".$step5."<br>";
// step 6
$step6=hash("sha256",$step5);
echo "step6 ".$step6."<br>";
// step 7
$checksum=substr($step6,0,8);
echo "step7 ".$checksum."<br>";
// step 8
$step8=$step4.$checksum;
echo "step8 ".$step8."<br>";
//step 9
$step9=base58_encode($step8);
echo "step9 ".$step9."<br><br>";
This fails at the first step. Any help appreciated.
This is the output
step1 0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6
step2 32511e82d56dcea68eb774094e25bab0f8bdd9bc1eca1ceeda38c7a43aceddce
step3 7528c664cdc34c5ce809778eb688d32f89a538c0
step4 007528c664cdc34c5ce809778eb688d32f89a538c0
step5 86e76f4ff0bf0387339ac70a552e0fed615f7def34cc4809df1429e243f6c1fa
step6 b885b7225b370e7ff27ee0afb4f89b52b8675d5dc342d63de3abe7535f86cadb
step7 b885b722
step8 007528c664cdc34c5ce809778eb688d32f89a538c0b885b722
step9 1
Base58 function is
function base58_encode($input)
{
$alphabet = '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ';
$base_count = strval(strlen($alphabet));
$encoded = '';
while (floatval($input) >= floatval($base_count))
{
$div = bcdiv($input, $base_count);
$mod = bcmod($input, $base_count);
$encoded = substr($alphabet, intval($mod), 1) . $encoded;
$input = $div;
}
if (floatval($input) > 0)
{
$encoded = substr($alphabet, intval($input), 1) . $encoded;
}
return($encoded);
}
Solution below with thanks to Sammitch for spotting syntax and providing the base conversions.
<?php
// step 1
$publickey='0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6';
$step1=hexStringToByteString($publickey);
echo "step1 ".$publickey."<br>";
// step 2
$step2=hash("sha256",$step1);
echo "step2 ".$step2."<br>";
// step 3
$step3=hash('ripemd160',hexStringToByteString($step2));
echo "step3 ".$step3."<br>";
// step 4
$step4="00".$step3;
echo "step4 ".$step4."<br>";
// step 5
$step5=hash("sha256",hexStringToByteString($step4));
echo "step5 ".$step5."<br>";
// step 6
$step6=hash("sha256",hexStringToByteString($step5));
echo "step6 ".$step6."<br>";
// step 7
$checksum=substr($step6,0,8);
echo "step7 ".$checksum."<br>";
// step 8
$step8=$step4.$checksum;
echo "step8 ".$step8."<br>";
// step 9
// base conversion is from hex to base58 via decimal.
// Leading hex zero converts to 1 in base58 but it is dropped
// in the intermediate decimal stage. Simply added back manually.
$step9="1".bc_base58_encode(bc_hexdec($step8));
echo "step9 ".$step9."<br><br>";
?>
hash requires a byte string not a hex string. hexStringToByteString is
function hexStringToByteString($hexString){
$len=strlen($hexString);
$byteString="";
for ($i=0;$i<$len;$i=$i+2){
$charnum=hexdec(substr($hexString,$i,2));
$byteString.=chr($charnum);
}
return $byteString;
}
base conversion (thanks to Sammitch - amended to use Bitcoin base58)
// BCmath version for huge numbers
function bc_arb_encode($num, $basestr) {
if( ! function_exists('bcadd') ) {
Throw new Exception('You need the BCmath extension.');
}
$base = strlen($basestr);
$rep = '';
while( true ){
if( strlen($num) < 2 ) {
if( intval($num) <= 0 ) {
break;
}
}
$rem = bcmod($num, $base);
$rep = $basestr[intval($rem)] . $rep;
$num = bcdiv(bcsub($num, $rem), $base);
}
return $rep;
}
function bc_arb_decode($num, $basestr) {
if( ! function_exists('bcadd') ) {
Throw new Exception('You need the BCmath extension.');
}
$base = strlen($basestr);
$dec = '0';
$num_arr = str_split((string)$num);
$cnt = strlen($num);
for($i=0; $i < $cnt; $i++) {
$pos = strpos($basestr, $num_arr[$i]);
if( $pos === false ) {
Throw new Exception(sprintf('Unknown character %s at offset %d', $num_arr[$i], $i));
}
$dec = bcadd(bcmul($dec, $base), $pos);
}
return $dec;
}
// base 58 alias
function bc_base58_encode($num) {
return bc_arb_encode($num, '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
}
function bc_base58_decode($num) {
return bc_arb_decode($num, '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
}
//hexdec with BCmath
function bc_hexdec($num) {
return bc_arb_decode(strtolower($num), '0123456789abcdef');
}
function bc_dechex($num) {
return bc_arb_encode($num, '0123456789abcdef');
}
final output
step1 0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6
step2 600ffe422b4e00731a59557a5cca46cc183944191006324a447bdb2d98d4b408
step3 010966776006953d5567439e5e39f86a0d273bee
step4 00010966776006953d5567439e5e39f86a0d273bee
step5 445c7a8007a93d8733188288bb320a8fe2debd2ae1b47f0f50bc10bae845c094
step6 d61967f63c7dd183914a4ae452c9f6ad5d462ce3d277798075b107615c1a8a30
step7 d61967f6
step8 00010966776006953d5567439e5e39f86a0d273beed61967f6
step9 16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM
Look carefully at your variable names. $publickey is not the same as $publicKey - note capitalisation.
Your problems are as follow:
Variable names $publickey and $publicKey are not equivalent.
$checksum=substr($step6,0,4); should be $checksum=substr($step6,0,8); because you need two hex chars to represent one byte.
$step8=$step4+$checksum; should be $step8=$step4.$checksum;
Also, I don't know where your base58_encode() function comes from, but I hope it uses BCmath, because the number represented by 00ba084d3f143f2896809d3f1d7dffed472b39d8de7a39cf51 [step 8's result] is too large for PHP to handle internally.
edit
I'm super bored at work today, here's my conversion code with bonus BCmath for ginormous [say, 58-digit?] numbers.
<?php
// original arbitrary encode function
function arb_encode($num, $basestr) {
$base = strlen($basestr);
$rep = '';
while($num > 0) {
$rem = $num % $base;
$rep = $basestr[$rem] . $rep;
$num = ($num - $rem) / $base;
}
return $rep;
}
function arb_decode($num, $basestr) {
$base = strlen($basestr);
$dec = 0;
$num_arr = str_split((string)$num);
$cnt = strlen($num);
for($i=0; $i < $cnt; $i++) {
$pos = strpos($basestr, $num_arr[$i]);
if( $pos === false ) {
Throw new Exception(sprintf('Unknown character %s at offset %d', $num_arr[$i], $i));
}
$dec = ($dec * $base) + $pos;
}
return $dec;
}
// BCmath version for huge numbers
function bc_arb_encode($num, $basestr) {
if( ! function_exists('bcadd') ) {
Throw new Exception('You need the BCmath extension.');
}
$base = strlen($basestr);
$rep = '';
while( true ){
if( strlen($num) < 2 ) {
if( intval($num) <= 0 ) { break; }
}
$rem = bcmod($num, $base);
$rep = $basestr[intval($rem)] . $rep;
$num = bcdiv(bcsub($num, $rem), $base);
}
return $rep;
}
function bc_arb_decode($num, $basestr) {
if( ! function_exists('bcadd') ) {
Throw new Exception('You need the BCmath extension.');
}
$base = strlen($basestr);
$dec = '0';
$num_arr = str_split((string)$num);
$cnt = strlen($num);
for($i=0; $i < $cnt; $i++) {
$pos = strpos($basestr, $num_arr[$i]);
if( $pos === false ) {
Throw new Exception(sprintf('Unknown character %s at offset %d', $num_arr[$i], $i));
}
$dec = bcadd(bcmul($dec, $base), $pos);
}
return $dec;
}
// base 58 alias
function bc_base58_encode($num) {
return bc_arb_encode($num, '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ');
}
function bc_base58_decode($num) {
return bc_arb_decode($num, '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ');
}
//hexdec with BCmath
function bc_hexdec($num) {
return bc_arb_decode(strtolower($num), '0123456789abcdef');
}
function bc_dechex($num) {
return bc_arb_encode($num, '0123456789abcdef');
}
// example
$orig = '00ba084d3f143f2896809d3f1d7dffed472b39d8de7a39cf51';
$bten = bc_hexdec($orig);
$base58 = bc_base58_encode($bten);
$backten = bc_base58_decode($base58);
$back = bc_dechex($backten);
echo "Orig: " . $orig . "\n";
echo "bten: " . $bten . "\n";
echo "58: " . $base58 . "\n";
echo "ag10: " . $backten . "\n";
echo "Back: " . $back . "\n";
edit2
Don't use base_convert() for numbers this large, it appears to be unreliable. I was writing the necessary bc_arb_decode() counterparts and found that the input and output were differing using base_convert() versus arb_convert($num, '0123456789abcdef'); and after comparing the results with Wolfram Alpha it seems that PHP is incorrectly converting the number.
Hex: 00ba084d3f143f2896809d3f1d7dffed472b39d8de7a39cf51
PHP's decode: 4561501878697786606686086062428080084446806606846864824262
Mine: 4561501878697784703577561586669353227270827349968709865297
Wolfram Alpha: 4561501878697784703577561586669353227270827349968709865297
You can see that PHP is way off. [1.9E42 aka 1.9 quintillion septillion] I've updated my code to include the arb_decode() functions which appear to do things correctly.
Very Important!
Replace this: '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'
With this: '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
Using the wrong code here would cause Bitcoin transactions to fail or worse, cause coins to disappear to a phantom wallet where they can never be retrieved.
I am not a developer but I confirmed the correction. The Base58 symbol chart is here, https://en.bitcoin.it/wiki/Base58Check_encoding
I checked my work here http://brainwallet.org/
Enter the passphrase: "test address" without the quotes.
The public key is then: 047969a753f71135d4c792f384e546cd508514024b4ee40d12a014019b77d1b292763dfb8a108cf7a7119f80ca4a06e81b92464f5d8a7544d52cd2e641023a96d7
Your address result : 1gBG1mbVtyNTgGZhggJ21A6mnjbNtqPCSr
My result: 1Gch1MBvUZotGhzHGGj21b6MNKBoURpdsS
brainwallet.org result: 1Gch1MBvUZotGhzHGGj21b6MNKBoURpdsS
I hope this saves someone from a time consuming or costly error.
Does anybody know a PHP function for IMEI validation?
Short solution
You can use this (witchcraft!) solution, and simply check the string length:
function is_luhn($n) {
$str = '';
foreach (str_split(strrev((string) $n)) as $i => $d) {
$str .= $i %2 !== 0 ? $d * 2 : $d;
}
return array_sum(str_split($str)) % 10 === 0;
}
function is_imei($n){
return is_luhn($n) && strlen($n) == 15;
}
Detailed solution
Here's my original function that explains each step:
function is_imei($imei){
// Should be 15 digits
if(strlen($imei) != 15 || !ctype_digit($imei))
return false;
// Get digits
$digits = str_split($imei);
// Remove last digit, and store it
$imei_last = array_pop($digits);
// Create log
$log = array();
// Loop through digits
foreach($digits as $key => $n){
// If key is odd, then count is even
if($key & 1){
// Get double digits
$double = str_split($n * 2);
// Sum double digits
$n = array_sum($double);
}
// Append log
$log[] = $n;
}
// Sum log & multiply by 9
$sum = array_sum($log) * 9;
// Compare the last digit with $imei_last
return substr($sum, -1) == $imei_last;
}
Maybe can help you :
This IMEI number is something like this: ABCDEF-GH-IJKLMNO-X (without “-” characters)
For example: 350077523237513
In our example ABCDEF-GH-IJKLMNO-X:
AB is Reporting Body Identifier such as 35 = “British Approvals Board of Telecommunications (BABT)”
ABCDEF is Type Approval Code
GH is Final Assembly Code
IJKLMNO is Serial Number
X is Check Digit
Also this can help you : http://en.wikipedia.org/wiki/IMEI#Check_digit_computation
If i don't misunderstood, IMEI numbers using Luhn algorithm . So you can google this :) Or you can search IMEI algorithm
Maybe your good with the imei validator in the comments here:
http://www.php.net/manual/en/function.ctype-digit.php#77718
But I haven't tested it
Check this solution
<?php
function validate_imei($imei)
{
if (!preg_match('/^[0-9]{15}$/', $imei)) return false;
$sum = 0;
for ($i = 0; $i < 14; $i++)
{
$num = $imei[$i];
if (($i % 2) != 0)
{
$num = $imei[$i] * 2;
if ($num > 9)
{
$num = (string) $num;
$num = $num[0] + $num[1];
}
}
$sum += $num;
}
if ((($sum + $imei[14]) % 10) != 0) return false;
return true;
}
$imei = '868932036356090';
var_dump(validate_imei($imei));
?>
IMEI validation uses Luhn check algorithm. I found a link to a page where you can validate your IMEI. Furthermore, at the bottom of this page is a piece of code written in JavaScript to show how to calculate the 15th digit of IMEI and to valid IMEI. I might give you some ideas. You can check it out here http://imei.sms.eu.sk/index.html
Here is a jQuery solution which may be of use: https://github.com/madeinstefano/imei-validator
good fun from kasperhartwich
function validateImei($imei, $use_checksum = true) {
if (is_string($imei)) {
if (ereg('^[0-9]{15}$', $imei)) {
if (!$use_checksum) return true;
for ($i = 0, $sum = 0; $i < 14; $i++) {
$tmp = $imei[$i] * (($i%2) + 1 );
$sum += ($tmp%10) + intval($tmp/10);
}
return (((10 - ($sum%10)) %10) == $imei[14]);
}
}
return false;
}
I know I can do this easily by converting the IP addresses to decimal notation first using PHP built in functions like up2long and long2ip. I just want to be able to do the same using the standard IP address notation as an exercise.
The problem I am thinking goes like this: Given an starting IP address, say 192.168.1.100, and an ending IP address, say 201.130.22.10. Make the program that prints all the address numbers in that range (192.168.1.100, 192.168.1.101, … , 201.130.22.9, 201.130.22.10).
I was thinking that maybe the way to go would be to make a nested for loop inside a while condition until the first octet of the starting address matches the first octet of the ending address. Then execute the same block of code for the second octet and so on until the program reaches the ending address and finished.
I just started learning to program recently so it is quite possible that my of thinking and or writing code is far from elegant. If you were to this, how would you do it?
Something like this:
<?php
// works only for valid range
$start_ip = '10.0.0.1';
$end_ip = '10.0.20.1';
$start_arr = explode('.',$start_ip);
$end_arr = explode('.',$end_ip);
while($start_arr <= $end_arr)
{
echo implode('.',$start_arr) . '<br>';
$start_arr[3]++;
if($start_arr[3] == 256)
{
$start_arr[3] = 0;
$start_arr[2]++;
if($start_arr[2] == 256)
{
$start_arr[2] = 0;
$start_arr[1]++;
if($start_arr[1] == 256)
{
$start_arr[1] = 0;
$start_arr[0]++;
}
}
}
}
?>
This is much less complicated:
<?php
// works only for valid range
$start_ip = ip2long('10.0.0.1');
$end_ip = ip2long('10.0.20.1');
while($start_ip <= $end_ip){
echo long2ip($start_ip).'<br>';
$start_ip++;
}
?>
function getInBetweenIPs($startIP,$endIP){
$subIPS = array();
$start_ip = ip2long($startIP);
$end_ip = ip2long($endIP);
while($start_ip <= $end_ip){
$subIPS[]=long2ip($start_ip);
$start_ip++;
}
return $subIPS;
}
Increment (Add to):
<?php
function ipinc($i): string {
$i = explode(".", $i);
$a = $i[0];
$b = $i[1];
$c = $i[2];
$d = $i[3];
$d++;
if ($d > 255) {
$d = 0;
$c++;
}
if ($c > 255) {
$c = 0;
$b++;
}
if ($b > 255) {
$b = 0;
$a++;
}
if ($a > 255) {
die("IPv4 Range Exceeded");
}
return "$a.$b.$c.$d";
}
?>
Decrement (Take from):
<?php
function ipdec($i) {
$i = explode(".", $i);
$a = $i[0];
$b = $i[1];
$c = $i[2];
$d = $i[3];
$d--;
if ($d < 0) {
$d = 255;
$c--;
}
if ($c < 0) {
$c = 255;
$b--;
}
if ($b < 0) {
$b = 255;
$a--;
}
if ($a < 0) {
die("IPv4 Range Exceeded");
}
return "$a.$b.$c.$d";
}
?>
To test both functions, you can write a for loop to generate approximately 16 million IP addresses back and forth, you can pipe the output to a file and store the results that way.
<?php
require 'function.ipinc.php';
require 'function.ipdec.php';
print("Increment:\n");
for ($i = 0, $ip = "100.0.0.0"; $i <= 16777215; $i++) {
print("$ip\n");
$ip = ipinc($ip);
}
print("----------\n");
print("Decrement:\n");
for ($i = 0, $ip = "100.255.255.255"; $i <= 16777215; $i++) {
print("$ip\n");
$ip = ipdec($ip);
}
print("----------\n");
die("Finished!\n");
?>
If you don't like assigning values through variable declarations, modify the functions so you can use pass by reference instead.