0

0

PHP位运算符

php中文网

php中文网

发布时间:2016-07-30 13:30:44

|

1503人浏览过

|

来源于php中文网

原创

位运算符允许对整型数中指定的位进行求值和操作。

位运算符
例子 名称 结果
$a & $b And(按位与) 将把 $a 和 $b 中都为 1 的位设为 1。
$a | $b Or(按位或) 将把 $a 和 $b 中任何一个为 1 的位设为 1。
$a ^ $b Xor(按位异或) 将把 $a 和 $b 中一个为 1 另一个为 0 的位设为 1。
~ $a Not(按位取反) 将 $a 中为 0 的位设为 1,反之亦然。
$a Shift left(左移) 将 $a 中的位向左移动 $b 次(每一次移动都表示“乘以 2”)。
$a >> $b Shift right(右移) 将 $a 中的位向右移动 $b 次(每一次移动都表示“除以 2”)。

位移在 PHP 中是数学运算。向任何方向移出去的位都被丢弃。左移时右侧以零填充,符号位被移走意味着正负号不被保留。右移时左侧以符号位填充,意味着正负号被保留。

要用括号确保想要的优先级。例如 $a & $b == true 先进行比较再进行按位与;而 ($a & $b) == true 则先进行按位与再进行比较。

要注意数据类型的转换。如果左右参数都是字符串,则位运算符将对字符的 ASCII 值进行操作。

PHP 的 ini 设定 error_reporting 使用了按位的值,
提供了关闭某个位的真实例子。要显示除了提示级别
之外的所有错误,php.ini 中是这样用的:
E_ALL & ~E_NOTICE
具体运作方式是先取得 E_ALL 的值:
00000000000000000111011111111111
再取得 E_NOTICE 的值:
00000000000000000000000000001000
然后通过 ~ 将其取反:
11111111111111111111111111110111
最后再用按位与 AND(&)得到两个值中都设定了(为 1)的位:
00000000000000000111011111110111
另外一个方法是用按位异或 XOR(^)来取得只在
其中一个值中设定了的位:
E_ALL ^ E_NOTICE

error_reporting 也可用来演示怎样置位。只显示错误和可恢复
错误的方法是:
E_ERROR | E_RECOVERABLE_ERROR
也就是将 E_ERROR
00000000000000000000000000000001
和 E_RECOVERABLE_ERROR
00000000000000000001000000000000
用按位或 OR(|)运算符来取得在任何一个值中被置位的结果:
00000000000000000001000000000001

Example #1 整数的 AND,OR 和 XOR 位运算符

/*
 * Ignore the top section,
 * it is just formatting to make output clearer.
 */
$format '(%1$2d = %1$04b) = (%2$2d = %2$04b)'
        
' %3$s (%4$2d = %4$04b)' "\n";
echo 
 ---------     ---------  -- ---------
 result        value      op test
 ---------     ---------  -- ---------
EOH;
/*
 * Here are the examples.
 */
$values = array(01248);
$test 4;
echo 
"\n Bitwise AND \n";
foreach (
$values as $value) {
    
$result $value $test;
    
printf($format$result$value'&'$test);
}
echo 
"\n Bitwise Inclusive OR \n";
foreach (
$values as $value) {
    
$result $value $test;
    
printf($format$result$value'|'$test);
}
echo 
"\n Bitwise Exclusive OR (XOR) \n";
foreach (
$values as $value) {
    
$result $value $test;
    
printf($format$result$value'^'$test);
}
?>

立即学习PHP免费学习笔记(深入)”;

以上例程会输出:

 ---------     ---------  -- ---------
 result        value      op test
 ---------     ---------  -- ---------
 Bitwise AND
( 0 = 0000) = ( 0 = 0000) & ( 5 = 0101)
( 1 = 0001) = ( 1 = 0001) & ( 5 = 0101)
( 0 = 0000) = ( 2 = 0010) & ( 5 = 0101)
( 4 = 0100) = ( 4 = 0100) & ( 5 = 0101)
( 0 = 0000) = ( 8 = 1000) & ( 5 = 0101)

 Bitwise Inclusive OR
( 5 = 0101) = ( 0 = 0000) | ( 5 = 0101)
( 5 = 0101) = ( 1 = 0001) | ( 5 = 0101)
( 7 = 0111) = ( 2 = 0010) | ( 5 = 0101)
( 5 = 0101) = ( 4 = 0100) | ( 5 = 0101)
(13 = 1101) = ( 8 = 1000) | ( 5 = 0101)

 Bitwise Exclusive OR (XOR)
( 5 = 0101) = ( 0 = 0000) ^ ( 5 = 0101)
( 4 = 0100) = ( 1 = 0001) ^ ( 5 = 0101)
( 7 = 0111) = ( 2 = 0010) ^ ( 5 = 0101)
( 1 = 0001) = ( 4 = 0100) ^ ( 5 = 0101)
(13 = 1101) = ( 8 = 1000) ^ ( 5 = 0101)

Example #2 字符串的 XOR 运算符

echo 12 9// Outputs '5'
echo "12" "9"// Outputs the Backspace character (ascii 8)
                 // ('1' (ascii 49)) ^ ('9' (ascii 57)) = #8
echo "hallo" "hello"// Outputs the ascii values #0 #4 #0 #0 #0
                        // 'a' ^ 'e' = #4
echo "3"// Outputs 1
              // 2 ^ ((int)"3") == 1
echo "2" 3// Outputs 1
              // ((int)"2") ^ 3 == 1
?>

Example #3 整数的位移

/*
 * Here are the examples.
 */
echo "\n--- BIT SHIFT RIGHT ON POSITIVE INTEGERS ---\n";
$val 4;
$places 1;
$res $val >> $places;
p($res$val'>>'$places'copy of sign bit shifted into left side');
$val 4;
$places 2;
$res $val >> $places;
p($res$val'>>'$places);
$val 4;
$places 3;
$res $val >> $places;
p($res$val'>>'$places'bits shift out right side');
$val 4;
$places 4;
$res $val >> $places;
p($res$val'>>'$places'same result as above; can not shift beyond 0');
echo 
"\n--- BIT SHIFT RIGHT ON NEGATIVE INTEGERS ---\n";
$val = -4;
$places 1;
$res $val >> $places;
p($res$val'>>'$places'copy of sign bit shifted into left side');
$val = -4;
$places 2;
$res $val >> $places;
p($res$val'>>'$places'bits shift out right side');
$val = -4;
$places 3;
$res $val >> $places;
p($res$val'>>'$places'same result as above; can not shift beyond -1');
echo 
"\n--- BIT SHIFT LEFT ON POSITIVE INTEGERS ---\n";
$val 4;
$places 1;
$res $val $places;
p($res$val'$places'zeros fill in right side');
$val 4;
$places = (PHP_INT_SIZE 8) - 4;
$res $val $places;
p($res$val'$places);
$val 4;
$places = (PHP_INT_SIZE 8) - 3;
$res $val $places;
p($res$val'$places'sign bits get shifted out');
$val 4;
$places = (PHP_INT_SIZE 8) - 2;
$res $val $places;
p($res$val'$places'bits shift out left side');
echo 
"\n--- BIT SHIFT LEFT ON NEGATIVE INTEGERS ---\n";
$val = -4;
$places 1;
$res $val $places;
p($res$val'$places'zeros fill in right side');
$val = -4;
$places = (PHP_INT_SIZE 8) - 3;
$res $val $places;
p($res$val'$places);
$val = -4;
$places = (PHP_INT_SIZE 8) - 2;
$res $val $places;
p($res$val'$places'bits shift out left side, including sign bit');
/*
 * Ignore this bottom section,
 * it is just formatting to make output clearer.
 */
function p($res$val$op$places$note '') {
    
$format '%0' . (PHP_INT_SIZE 8) . "b\n";
    
printf("Expression: %d = %d %s %d\n"$res$val$op$places);
    echo 
" Decimal:\n";
    
printf("  val=%d\n"$val);
    
printf("  res=%d\n"$res);
    echo 
" Binary:\n";
    
printf('  val=' $format$val);
    
printf('  res=' $format$res);
    if (
$note) {
        echo 
" NOTE: $note\n";
    }
    echo 
"\n";
}
?>

以上例程在 32 位机器上的输出:

--- BIT SHIFT RIGHT ON POSITIVE INTEGERS ---
Expression: 2 = 4 >> 1
 Decimal:
  val=4
  res=2
 Binary:
  val=00000000000000000000000000000100
  res=00000000000000000000000000000010
 NOTE: copy of sign bit shifted into left side

Expression: 1 = 4 >> 2
 Decimal:
  val=4
  res=1
 Binary:
  val=00000000000000000000000000000100
  res=00000000000000000000000000000001

Expression: 0 = 4 >> 3
 Decimal:
  val=4
  res=0
 Binary:
  val=00000000000000000000000000000100
  res=00000000000000000000000000000000
 NOTE: bits shift out right side

Expression: 0 = 4 >> 4
 Decimal:
  val=4
  res=0
 Binary:
  val=00000000000000000000000000000100
  res=00000000000000000000000000000000
 NOTE: same result as above; can not shift beyond 0


--- BIT SHIFT RIGHT ON NEGATIVE INTEGERS ---
Expression: -2 = -4 >> 1
 Decimal:
  val=-4
  res=-2
 Binary:
  val=11111111111111111111111111111100
  res=11111111111111111111111111111110
 NOTE: copy of sign bit shifted into left side

Expression: -1 = -4 >> 2
 Decimal:
  val=-4
  res=-1
 Binary:
  val=11111111111111111111111111111100
  res=11111111111111111111111111111111
 NOTE: bits shift out right side

Expression: -1 = -4 >> 3
 Decimal:
  val=-4
  res=-1
 Binary:
  val=11111111111111111111111111111100
  res=11111111111111111111111111111111
 NOTE: same result as above; can not shift beyond -1


--- BIT SHIFT LEFT ON POSITIVE INTEGERS ---
Expression: 8 = 4 << 1
 Decimal:
  val=4
  res=8
 Binary:
  val=00000000000000000000000000000100
  res=00000000000000000000000000001000
 NOTE: zeros fill in right side

Expression: 1073741824 = 4 << 28
 Decimal:
  val=4
  res=1073741824
 Binary:
  val=00000000000000000000000000000100
  res=01000000000000000000000000000000

Expression: -2147483648 = 4 << 29
 Decimal:
  val=4
  res=-2147483648
 Binary:
  val=00000000000000000000000000000100
  res=10000000000000000000000000000000
 NOTE: sign bits get shifted out

Expression: 0 = 4 << 30
 Decimal:
  val=4
  res=0
 Binary:
  val=00000000000000000000000000000100
  res=00000000000000000000000000000000
 NOTE: bits shift out left side


--- BIT SHIFT LEFT ON NEGATIVE INTEGERS ---
Expression: -8 = -4 << 1
 Decimal:
  val=-4
  res=-8
 Binary:
  val=11111111111111111111111111111100
  res=11111111111111111111111111111000
 NOTE: zeros fill in right side

Expression: -2147483648 = -4 << 29
 Decimal:
  val=-4
  res=-2147483648
 Binary:
  val=11111111111111111111111111111100
  res=10000000000000000000000000000000

Expression: 0 = -4 << 30
 Decimal:
  val=-4
  res=0
 Binary:
  val=11111111111111111111111111111100
  res=00000000000000000000000000000000
 NOTE: bits shift out left side, including sign bit

以上例程在 64 位机器上的输出:

--- BIT SHIFT RIGHT ON POSITIVE INTEGERS ---
Expression: 2 = 4 >> 1
 Decimal:
  val=4
  res=2
 Binary:
  val=0000000000000000000000000000000000000000000000000000000000000100
  res=0000000000000000000000000000000000000000000000000000000000000010
 NOTE: copy of sign bit shifted into left side

Expression: 1 = 4 >> 2
 Decimal:
  val=4
  res=1
 Binary:
  val=0000000000000000000000000000000000000000000000000000000000000100
  res=0000000000000000000000000000000000000000000000000000000000000001

Expression: 0 = 4 >> 3
 Decimal:
  val=4
  res=0
 Binary:
  val=0000000000000000000000000000000000000000000000000000000000000100
  res=0000000000000000000000000000000000000000000000000000000000000000
 NOTE: bits shift out right side

Expression: 0 = 4 >> 4
 Decimal:
  val=4
  res=0
 Binary:
  val=0000000000000000000000000000000000000000000000000000000000000100
  res=0000000000000000000000000000000000000000000000000000000000000000
 NOTE: same result as above; can not shift beyond 0


--- BIT SHIFT RIGHT ON NEGATIVE INTEGERS ---
Expression: -2 = -4 >> 1
 Decimal:
  val=-4
  res=-2
 Binary:
  val=1111111111111111111111111111111111111111111111111111111111111100
  res=1111111111111111111111111111111111111111111111111111111111111110
 NOTE: copy of sign bit shifted into left side

Expression: -1 = -4 >> 2
 Decimal:
  val=-4
  res=-1
 Binary:
  val=1111111111111111111111111111111111111111111111111111111111111100
  res=1111111111111111111111111111111111111111111111111111111111111111
 NOTE: bits shift out right side

Expression: -1 = -4 >> 3
 Decimal:
  val=-4
  res=-1
 Binary:
  val=1111111111111111111111111111111111111111111111111111111111111100
  res=1111111111111111111111111111111111111111111111111111111111111111
 NOTE: same result as above; can not shift beyond -1


--- BIT SHIFT LEFT ON POSITIVE INTEGERS ---
Expression: 8 = 4 << 1
 Decimal:
  val=4
  res=8
 Binary:
  val=0000000000000000000000000000000000000000000000000000000000000100
  res=0000000000000000000000000000000000000000000000000000000000001000
 NOTE: zeros fill in right side

Expression: 4611686018427387904 = 4 << 60
 Decimal:
  val=4
  res=4611686018427387904
 Binary:
  val=0000000000000000000000000000000000000000000000000000000000000100
  res=0100000000000000000000000000000000000000000000000000000000000000

Expression: -9223372036854775808 = 4 << 61
 Decimal:
  val=4
  res=-9223372036854775808
 Binary:
  val=0000000000000000000000000000000000000000000000000000000000000100
  res=1000000000000000000000000000000000000000000000000000000000000000
 NOTE: sign bits get shifted out

Expression: 0 = 4 << 62
 Decimal:
  val=4
  res=0
 Binary:
  val=0000000000000000000000000000000000000000000000000000000000000100
  res=0000000000000000000000000000000000000000000000000000000000000000
 NOTE: bits shift out left side


--- BIT SHIFT LEFT ON NEGATIVE INTEGERS ---
Expression: -8 = -4 << 1
 Decimal:
  val=-4
  res=-8
 Binary:
  val=1111111111111111111111111111111111111111111111111111111111111100
  res=1111111111111111111111111111111111111111111111111111111111111000
 NOTE: zeros fill in right side

Expression: -9223372036854775808 = -4 << 61
 Decimal:
  val=-4
  res=-9223372036854775808
 Binary:
  val=1111111111111111111111111111111111111111111111111111111111111100
  res=1000000000000000000000000000000000000000000000000000000000000000

Expression: 0 = -4 << 62
 Decimal:
  val=-4
  res=0
 Binary:
  val=1111111111111111111111111111111111111111111111111111111111111100
  res=0000000000000000000000000000000000000000000000000000000000000000
 NOTE: bits shift out left side, including sign bit

Warning

不要在 32 位系统下向右移超过 32 位。不要在结果可能超过 32 的情况下左移。使用 gmp 扩展对超出 PHP_INT_MAX 的数值来进行位操作。

参见 pack()unpack()gmp_and()gmp_or()gmp_xor()gmp_testbit() 和 gmp_clrbit()

add a note add a note

User Contributed Notes 43 notes

up

SmartB2B行业电子商务
SmartB2B行业电子商务

SmartB2B 是一款基于PHP、MySQL、Smarty的B2B行业电子商务网站管理系统,系统提供了供求模型、企业模型、产品模型、人才招聘模型、资讯模型等模块,适用于想在行业里取得领先地位的企业快速假设B2B网站,可以运行于Linux与Windows等多重服务器环境,安装方便,使用灵活。 系统使用当前流行的PHP语言开发,以MySQL为数据库,采用B/S架构,MVC模式开发。融入了模型化、模板

下载

down

46wbcarts at juno dot com ?
3 years ago

BITWISE FLAGS for Custom PHP Objects
Sometimes I need a custom PHP Object that holds several boolean TRUE or FALSE values. I could easily include a variable for each of them, but as always, code has a way to get unweildy pretty fast. A more intelligent approach always seems to be the answer, even if it seems to be overkill at first.
I start with an abstract base class which will hold a single integer variable called $flags. This simple integer can hold 32 TRUE or FALSE boolean values. Another thing to consider is to just set certain BIT values without disturbing any of the other BITS -- so included in the class definition is the setFlag($flag, $value) function, which will set only the chosen bit. Here's the abstract base class definition: 
# BitwiseFlag.php
abstract class BitwiseFlag
{
  protected 
$flags;
  
/*
   * Note: these functions are protected to prevent outside code
   * from falsely setting BITS. See how the extending class 'User'
   * handles this.
   *
   */
  
protected function isFlagSet($flag)
  {
    return ((
$this->flags $flag) == $flag);
  }
  protected function 
setFlag($flag$value)
  {
    if(
$value)
    {
      
$this->flags |= $flag;
    }
    else
    {
      
$this->flags &= ~$flag;
    }
  }
}
?>

The class above is abstract and cannot be instantiated, so an extension is required. Below is a simple extension called User -- which is severely truncated for clarity. Notice I am defining const variables AND methods to use them.
# User.php
require('BitwiseFlag.php');
class 
User extends BitwiseFlag
{
  const 
FLAG_REGISTERED 1// BIT #1 of $flags has the value 1
  
const FLAG_ACTIVE 2;     // BIT #2 of $flags has the value 2
  
const FLAG_MEMBER 4;     // BIT #3 of $flags has the value 4
  
const FLAG_ADMIN 8;      // BIT #4 of $flags has the value 8
  
public function isRegistered(){
    return 
$this->isFlagSet(self::FLAG_REGISTERED);
  }
  public function 
isActive(){
    return 
$this->isFlagSet(self::FLAG_ACTIVE);
  }
  public function 
isMember(){
    return 
$this->isFlagSet(self::FLAG_MEMBER);
  }
  public function 
isAdmin(){
    return 
$this->isFlagSet(self::FLAG_ADMIN);
  }
  public function 
setRegistered($value){
    
$this->setFlag(self::FLAG_REGISTERED$value);
  }
  public function 
setActive($value){
    
$this->setFlag(self::FLAG_ACTIVE$value);
  }
  public function 
setMember($value){
    
$this->setFlag(self::FLAG_MEMBER$value);
  }
  public function 
setAdmin($value){
    
$this->setFlag(self::FLAG_ADMIN$value);
  }
  public function 
__toString(){
    return 
'User [' .
      (
$this->isRegistered() ? 'REGISTERED' '') .
      (
$this->isActive() ? ' ACTIVE' '') .
      (
$this->isMember() ? ' MEMBER' '') .
      (
$this->isAdmin() ? ' ADMIN' '') .
    
']';
  }
}
?>

This seems like a lot of work, but we have addressed many issues, for example, using and maintaining the code is easy, and the getting and setting of flag values make sense. With the User class, you can now see how easy and intuitive bitwise flag operations become.
require('User.php')
$user = new User();
$user->setRegistered(true);
$user->setActive(true);
$user->setMember(true);
$user->setAdmin(true);
echo 
$user;  // outputs: User [REGISTERED ACTIVE MEMBER ADMIN]
?>

up

down

6zlel grxnslxves13 at hotmail dot com~=s/x/ee/g ?
9 years ago

I refer to Eric Swanson's post on Perl VS PHP's implementation of xor. 
Actually, this is not an issue with the implementation of XOR,  but a lot more to do with the lose-typing policy that PHP adopts. 
Freely switching between int and float is good for most cases, but problems happen when your value is near the word size of your machine. Which is to say, 32-bit machines will encounter problems with values that hover around 0x80000000 - primarily because PHP does not support unsigned integers.
using bindec/decbin would address this issue as a work-around to do unsigned-int xor, but here's the real picture (i'm not claiming that this code will perform better, but this would be a better pedagogical code):
function unsigned_xor32 ($a$b
{
        
$a1 $a 0x7FFF0000;
        
$a2 $a 0x0000FFFF;
        
$a3 $a 0x80000000;
        
$b1 $b 0x7FFF0000;
        
$b2 $b 0x0000FFFF;
        
$b3 $b 0x80000000;
        
$c = ($a3 != $b3) ? 0x80000000 0;
        return ((
$a1 $b1) |($a2 $b2)) + $c;
}
$x 3851235679;
$y 43814;
echo 
"
This is the value we want"
;
echo 
"
3851262585"
;
echo 
"
The result of a native xor operation on integer values is treated as a signed integer"
;
echo 
"
"
.($x $y);
echo 
"
We therefore perform the MSB separately"
;
echo 
"
"
.unsigned_xor32($x$y);
?>

This is really foundation stuff, but for those of you who missed this in college, there seems to be something on 2's complement here: 
http://www.evergreen.edu/biophysics/technotes/program/2s_comp.htm

up

down

3sag at ich dot net ?
2 years ago

me reimplement for bitwise NOT (~)
    protected function flipBin($number) {
        $bin = str_pad(base_convert($number, 10, 2), 32, 0, STR_PAD_LEFT);
        for ($i = 0; $i             switch ($bin{$i}) {
                case '0' :
                    $bin{$i} = '1';
                    break;
                case '1' :
                    $bin{$i} = '0';
                    break;
            }
        }
        return bindec($bin);
    }
the benefit is, it works with numbers greater MAX_INT

up

down

3vivekanand dot pathak25 at gmail dot com ?
2 years ago

$a =     9;
$b =     10;
echo $a & $b;
place value   128  64  32  16   8  4   2   1
$a                     0      0    0     0    1  0   0   1   =9
$b                     0      0    0     0    1   0  1   0   =10
result   8  
only bit they share together is the 8 bit. So 8 gets returned.
  $a =     36;
$b =     103;
echo $a & $b;
place value   128  64  32  16   8    4   2   1
$a                     0      0    1     0    0    1   0   0   =36
$b                     0      1    1     0    0    1   1   1   =103
result  32+4 = 36
the only bits these two share together are the bits 32 and 4 which when added together return 36.
$a =     9;
$b =     10;
echo $a | $b;
place value   128  64  32  16   8  4   2   1
$a                     0      0    0     0    1  0   0   1   =9
$b                     0      0    0     0    1   0  1   0   =10
result 8+2+1 = 11
3 bits set, in the 8, 2, and 1 column.add those up 8+2+1 and you get 11
$a =     9;
$b =     10;
echo $a ^ $b;
place value   128  64  32  16   8  4   2   1
$a                     0      0    0     0    1  0   0   1   =9
$b                     0      0    0     0    1   0  1   0   =10
result  2+1 = 3
the 2 bit and the 1 bit that they each have set but don't share. Soooo 2+1 = 3

up

down

3erich at seachawaii dot com ?
2 years ago

Just a note regarding negative shift values, as the documentation states each shift is an integer multiply or divide (left or right respectively) by 2.  That means a negative shift value (the right hand operand) effects the sign of the shift and NOT the direction of the shift as I would have expected.  
FE. 0xff >> -2 results in 0x0 
and 0xff

up

down

4cw3theophilus at gmail dot com ?
6 years ago

For those who are looking for a circular bit shift function in PHP (especially useful for cryptographic functions) that works with negtive values, here is a little function I wrote:
(Note: It took me almost a whole day to get this to work with negative $num values (I couldn't figure out why it sometimes worked and other times didn't), because PHP only has an arithmatic and not a logical bitwise right shift like I am used to. I.e. 0x80000001>>16 will ouputs (in binary) "1111 1111 1111 1111 1000 0000 0000 0000" instead of "0000 0000 0000 0000 1000 0000 0000 0000" like you would expect. To fix this you have to apply the mask (by bitwise &) equal to 0x7FFFFFFF right shifted one less than the offset you are shifting by.)
function circular_shift($num,$offset) { //Do a nondestructive circular bitwise shift, if offset positive shift left, if negative shift right
    
$num=(int)$num;
    
$mask=0x7fffffff//Mask to cater for the fact that PHP only does arithmatic right shifts and not logical i.e. PHP doesn't give expected output when right shifting negative values
    
if ($offset>0) {
        
$num=($num$offset%32) | (($num>>(32-$offset%32)) & ($mask>>(31-$offset%32)));
    }
    elseif (
$offset0){
        
$offset=abs($offset);
        
$num=(($num>>$offset%32) & ($mask>>(-1+$offset%32))) | ($num32-$offset%32));
    }
    return 
$num
}
?>

up

down

3m0sh at hotmail dot com ?
7 years ago

@greenone - nice function, thanks. I've adapted it for key usage:
function bitxor($str$key) {
    
$xorWidth PHP_INT_SIZE*8;
    
// split
    
$o1 str_split($str$xorWidth);
    
$o2 str_split(str_pad(''strlen($str), $key), $xorWidth);
    
$res '';
    
$runs count($o1);
    for(
$i=0;$i$runs;$i++)
        
$res .= decbin(bindec($o1[$i]) ^ bindec($o2[$i]));       
    return 
$res;
}
?>

up

down

3Eric Swanson ?
9 years ago

Perl vs. PHP implementation of the ^ operator:
After attempting to translate a Perl module into PHP, I realized that Perl's implementation of the ^ operator is different than the PHP implementation.  By default, Perl treats the variables as floats and PHP as integers.  I was able to verify the PHP use of the operator by stating "use integer;" within the Perl module, which output the exact same result as PHP was using.
The logical decision would be to cast every variable as (float) when using the ^ operator in PHP.  However, this will not yield the same results.  After about a half hour of banging my head against the wall, I discovered a gem and wrote a function using the binary-decimal conversions in PHP.
/*
not having much experience with bitwise operations, I cannot tell you that this is the BEST solution, but it certainly is a solution that finally works and always returns the EXACT same result Perl provides.
*/
function binxor($a, $b) {
    return bindec(decbin((float)$a ^ (float)$b));
}
//normal PHP code will not yeild the same result as Perl
$result = 3851235679 ^ 43814; //= -443704711
//to get the same result as Perl
$result = binxor(3851235679, 43814); //= 3851262585
//YIPPEE!!!
//to see the differences, try the following
$a = 3851235679 XOR 43814;
$b = 3851235679 ^ 43814; //integer result
$c = (float)3851235679 ^ (float)43814; //same as $b
$d = binxor(3851235679, 43814); //same as Perl!!
echo("A: $a
");
echo("B: $b
");
echo("C: $c
");
echo("D: $d
");

up

down

10grayda dot NOSPAM at DONTSPAM dot solidinc dot org ?
6 years ago

Initially, I found bitmasking to be a confusing concept and found no use for it. So I've whipped up this code snippet in case anyone else is confused:
    // The various details a vehicle can have
    
$hasFourWheels 1;
    
$hasTwoWheels  2;
    
$hasDoors      4;
    
$hasRedColour  8;
    
$bike          $hasTwoWheels;
    
$golfBuggy     $hasFourWheels;
    
$ford          $hasFourWheels $hasDoors;
    
$ferrari       $hasFourWheels $hasDoors $hasRedColour;
    
$isBike        $hasFourWheels $bike# False, because $bike doens't have four wheels
    
$isGolfBuggy   $hasFourWheels $golfBuggy# True, because $golfBuggy has four wheels
    
$isFord        $hasFourWheels $ford# True, because $ford $hasFourWheels
?>

And you can apply this to a lot of things, for example, security:
    // Security permissions:
    
$writePost 1;
    
$readPost 2;
    
$deletePost 4;
    
$addUser 8;
    
$deleteUser 16;
    
    
// User groups:
    
$administrator $writePost $readPosts $deletePosts $addUser $deleteUser;
    
$moderator $readPost $deletePost $deleteUser;
    
$writer $writePost $readPost;
    
$guest $readPost;
    
// function to check for permission
    
function checkPermission($user$permission) {
        if(
$user $permission) {
            return 
true;
        } else {
            return 
false;
        }
    }
    
// Now we apply all of this!
    
if(checkPermission($administrator$deleteUser)) {
        
deleteUser("Some User"); # This is executed because $administrator can $deleteUser
    
}
?>

Once you get your head around it, it's VERY useful! Just remember to raise each value by the power of two to avoid problems

up

down

6ivoras at gmail dot com ?
4 years ago

As an additional curiosity, for some reason the result of the operation ("18" & "32") is "10". In other words, try avoiding using the binary operators on strings :)

up

down

10?
10 years ago

A bitwise operators practical case :
    // We want to know the red, green and blue values of this color :
    
$color 0xFEA946 ;
    
$red $color >> 16 ;
    
$green = ($color 0x00FF00) >> ;
    
$blue $color 0x0000FF ;
    
printf('Red : %X (%d), Green : %X (%d), Blue : %X (%d)',
        
$red$red$green$green$blue$blue) ;
    
// Will display...
    // Red : FE (254), Green : A9 (169), Blue : 46 (70)
?>

up

down

4zooly at globmi dot com ?
5 years ago

Here is an example for bitwise leftrotate and rightrotate.
Note that this function works only with decimal numbers - other types can be converted with pack().
function rotate $decimal$bits) {
  
$binary decbin($decimal);
  return (
    
bindec(substr($binary$bits).substr($binary0$bits))
  );
}
// Rotate 124124 (1111100) to the left with 1 bits
echo rotate(1241241);
// = 121 (1111001)
// Rotate 124124 (1111100) to the right with 3 bits
echo rotate(124124, -3);
// = 79 (1001111)
?>

up

down

3josh at joshstrike dot com ?
4 years ago

More referencing this for myself than anything... if you need to iterate through every possible binary combination where $n number of flags are set to 1 in a mask of $bits length: 
echo masksOf(3,10); 
function 
masksOf($n,$bits) { 
    
$u pow(2,$bits)-1//start value, full flags on. 
    
$masks = array(); 
    while (
$u>0) { 
        
$z numflags($u); 
        if (
$z==$narray_push($masks,$u); 
        
$u--; 
    } 
    return (
$masks);    

function 
numflags($n) { 
    
$k 0
    while (
$n) { 
        
$k += $n 1
        
$n $n >> 1
    } 
    return (
$k); 
//    alternately: 
//    $u = 0; 
//    for ($k=1;$k//        $u+=($n&$k?1:0); 
//    } 
//    return ($u); 

?>

up

down

4spencer-p-moy at example dot com ?
3 years ago

The NOT or complement operator ( ~ ) and negative binary numbers can be confusing.
~2 = -3  because you use the formula  ~x = -x - 1  The bitwise complement of a decimal number is the negation of the number minus 1.
NOTE: just using 4 bits here for the examples below but in reality PHP uses 32 bits.
Converting a negative decimal number (ie: -3) into binary takes 3 steps:
1) convert the positive version of the decimal number into binary (ie: 3 = 0011)
2) flips the bits (ie: 0011 becomes 1100)
3) add 1 (ie: 1100  + 0001 = 1101)
You might be wondering how does 1101 = -3. Well PHP uses the method "2's complement" to render negative binary numbers. If the left most bit is a 1 then the binary number is negative and you flip the bits and add 1. If it is 0 then it is positive and you don't have to do anything. So 0010 would be a positive 2. If it is 1101, it is negative and you flip the bits to get 0010. Add 1 and you get 0011 which equals -3.

up

down

4Silver ?
6 ye

相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Golang 网络安全与加密实战
Golang 网络安全与加密实战

本专题系统讲解 Golang 在网络安全与加密技术中的应用,包括对称加密与非对称加密(AES、RSA)、哈希与数字签名、JWT身份认证、SSL/TLS 安全通信、常见网络攻击防范(如SQL注入、XSS、CSRF)及其防护措施。通过实战案例,帮助学习者掌握 如何使用 Go 语言保障网络通信的安全性,保护用户数据与隐私。

2

2026.01.29

俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

446

2026.01.28

包子漫画在线官方入口大全
包子漫画在线官方入口大全

本合集汇总了包子漫画2026最新官方在线观看入口,涵盖备用域名、正版无广告链接及多端适配地址,助你畅享12700+高清漫画资源。阅读专题下面的文章了解更多详细内容。

145

2026.01.28

ao3中文版官网地址大全
ao3中文版官网地址大全

AO3最新中文版官网入口合集,汇总2026年主站及国内优化镜像链接,支持简体中文界面、无广告阅读与多设备同步。阅读专题下面的文章了解更多详细内容。

258

2026.01.28

php怎么写接口教程
php怎么写接口教程

本合集涵盖PHP接口开发基础、RESTful API设计、数据交互与安全处理等实用教程,助你快速掌握PHP接口编写技巧。阅读专题下面的文章了解更多详细内容。

9

2026.01.28

php中文乱码如何解决
php中文乱码如何解决

本文整理了php中文乱码如何解决及解决方法,阅读节专题下面的文章了解更多详细内容。

13

2026.01.28

Java 消息队列与异步架构实战
Java 消息队列与异步架构实战

本专题系统讲解 Java 在消息队列与异步系统架构中的核心应用,涵盖消息队列基本原理、Kafka 与 RabbitMQ 的使用场景对比、生产者与消费者模型、消息可靠性与顺序性保障、重复消费与幂等处理,以及在高并发系统中的异步解耦设计。通过实战案例,帮助学习者掌握 使用 Java 构建高吞吐、高可靠异步消息系统的完整思路。

10

2026.01.28

Python 自然语言处理(NLP)基础与实战
Python 自然语言处理(NLP)基础与实战

本专题系统讲解 Python 在自然语言处理(NLP)领域的基础方法与实战应用,涵盖文本预处理(分词、去停用词)、词性标注、命名实体识别、关键词提取、情感分析,以及常用 NLP 库(NLTK、spaCy)的核心用法。通过真实文本案例,帮助学习者掌握 使用 Python 进行文本分析与语言数据处理的完整流程,适用于内容分析、舆情监测与智能文本应用场景。

25

2026.01.27

拼多多赚钱的5种方法 拼多多赚钱的5种方法
拼多多赚钱的5种方法 拼多多赚钱的5种方法

在拼多多上赚钱主要可以通过无货源模式一件代发、精细化运营特色店铺、参与官方高流量活动、利用拼团机制社交裂变,以及成为多多进宝推广员这5种方法实现。核心策略在于通过低成本、高效率的供应链管理与营销,利用平台社交电商红利实现盈利。

124

2026.01.26

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Excel 教程
Excel 教程

共162课时 | 14.1万人学习

Pandas 教程
Pandas 教程

共15课时 | 1.0万人学习

C# 教程
C# 教程

共94课时 | 7.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号