function hashCode($s)
{
    $h = 0;
    $len = strlen($s);
    for ($i = 0; $i < $len; $i++) {
        $h = overflow32(31 * $h + ord($s[$i]));
    }
    return $h;
}
 /**
  * Efficient method to check if a range of bits is set, or not set.
  *
  * @param start start of range, inclusive.
  * @param end end of range, exclusive
  * @param value if true, checks that bits in range are set, otherwise checks that they are not set
  * @return true iff all bits are set or not set in range, according to value argument
  * @throws InvalidArgumentException if end is less than or equal to start
  */
 public function isRange($start, $end, $value)
 {
     if ($end < $start) {
         throw new InvalidArgumentException();
     }
     if ($end == $start) {
         return true;
         // empty range matches
     }
     $end--;
     // will be easier to treat this as the last actually set bit -- inclusive
     $firstInt = intval($start / 32);
     $lastInt = intval($end / 32);
     for ($i = $firstInt; $i <= $lastInt; $i++) {
         $firstBit = $i > $firstInt ? 0 : $start & 0x1f;
         $lastBit = $i < $lastInt ? 31 : $end & 0x1f;
         $mask = 0;
         if ($firstBit == 0 && $lastBit == 31) {
             $mask = -1;
         } else {
             $mask = 0;
             for ($j = $firstBit; $j <= $lastBit; $j++) {
                 $mask = overflow32($mask | 1 << $j);
             }
         }
         // Return false if we're looking for 1s and the masked bits[i] isn't all 1s (that is,
         // equals the mask, or we're looking for 0s and the masked portion is not all 0s
         if (($this->bits[$i] & $mask) != ($value ? $mask : 0)) {
             return false;
         }
     }
     return true;
 }
 /**
  * <p>Sets a square region of the bit matrix to true.</p>
  *
  * @param $left;  The horizontal position to begin at (inclusive)
  * @param $top;  The vertical position to begin at (inclusive)
  * @param $width;  The width of the region
  * @param $height;  The height of the region
  */
 public function setRegion($left, $top, $width, $height)
 {
     if ($top < 0 || $left < 0) {
         throw new InvalidArgumentException("Left and top must be nonnegative");
     }
     if ($height < 1 || $width < 1) {
         throw new InvalidArgumentException("Height and width must be at least 1");
     }
     $right = $left + $width;
     $bottom = $top + $height;
     if ($bottom > $this->height || $right > $this->width) {
         //> this.height || right > this.width
         throw new InvalidArgumentException("The region must fit inside the matrix");
     }
     for ($y = $top; $y < $bottom; $y++) {
         $offset = $y * $this->rowSize;
         for ($x = $left; $x < $right; $x++) {
             $this->bits[$offset + intval($x / 32)] = overflow32($this->bits[$offset + intval($x / 32)] |= 1 << ($x & 0x1f));
         }
     }
 }