2

i want to shift a 16-bit variable in Php. but my code is not working. its just shifts the Lowest nibbles of each Byte. and leave The High nibble unchanged. first and third nibble shifts fine. but second and fourth is not.

public static function leftShift2Byte($in){
     $strarr = str_split($in);
     if($strarr[1]>chr(127)){
         $strarr[1] = $strarr[1]<<1;
         $strarr[0] = $strarr[0]<<1;
         $strarr[0]++;
     }else{
         $strarr[1] = $strarr[1]<<1;
         $strarr[0] = $strarr[0]<<1;
     }
     return $strarr[0].$strarr[1];
 } 
Vishnu Bhadoriya
  • 1,655
  • 1
  • 20
  • 28
Abilogos
  • 4,777
  • 2
  • 19
  • 39

3 Answers3

1

Unlike C, dereferencing a string by index in PHP doesn't produce a numeric variable, but a 1-byte string:

$str = 'as';
var_dump($str[0]); 
// prints: string(1) "a"

Strings are not subject to bitwise operations. Or more precisely: they are parsed as integers before performing a bitwise operation. That's why if you pass it a string containing numeric characters, it would appear as 'shifting the lowest nibble', while in reality it does something completely different:

var_dump(leftShift2Byte('01'));
// prints: string(2) "02"
// That is:
// - '0' parsed as integer to 0, shifted 1 bit, got 0, concatenated as '0'
// - '1' parsed as 1, shifted to 2, concatenated as '2'

You have to explicitly cast 1-byte strings to byte codes by calling ord and then back by calling chr:

function leftShift2ByteOrd($in){
    $strarr = str_split($in);
    $numarr = array_map('ord', $strarr);
    $carry = $numarr[1] | 0x80;
    $numarr[1] = $numarr[1] << 1;
    $numarr[0] = $numarr[0] << 1;
    if ($carry) {
        $numarr[0]++;
    }
    return chr($numarr[0]) . chr($numarr[1]);
}

var_dump(leftShift2ByteOrd('01'));
// prints: string(2) "ab"
ob-ivan
  • 785
  • 1
  • 8
  • 17
0

finnaly i found out that should change the string to The number type in order to shift it. like this one:

public function nextChildCode($childs){
    $mask=bindec('0000000000000001');
    $counter=0;
    $childNum=ord($childs{1})+( ord($childs{0})*256 );
    //$childNum=32767;
    while((($mask & $childNum)!=0)&& $counter<17){
        $mask=$mask<<1;
        $counter++;
    }

    if($counter<16){
        return dechex($counter) ;
    }else{
        return NULL;
    }
}
Abilogos
  • 4,777
  • 2
  • 19
  • 39
0

Bitwise operator << or >> left or right


echo 1010<<2 ;

dılo sürücü
  • 3,821
  • 1
  • 26
  • 28