data = $data; } /** * @param int $numBytes * @return bool */ public function skip(int $numBytes): bool { if ($numBytes < 0 || $numBytes > strlen($this->data)) return false; $this->offset += $numBytes; return $true; } /** * @param int $pos * @return bool */ public function seek(int $pos): bool { if ($pos < 0 || $pos > strlen($this->data)) return false; $this->offset = $pos; return true; } /** * @param int $offset * @param int $numBytes * @param bool $str * @return string */ public function read(int $offset, int $numBytes) { $this->seek($offset); $bytes = null; for ($i = $this->offset; $i < $this->offset + $numBytes; $i++) { $bytes .= $this->data[$i]; } return $bytes; } /** * @param int $offset * @param int $numBytes * @param bool $str * @return string */ public function readh(int $offset, int $numBytes, bool $str = true) { $this->seek($offset); $bytes = null; for ($i = $this->offset; $i < $this->offset + $numBytes; $i++) { $str ? $bytes .= $this->data[$i] : $bytes[] = $this->data[$i]; } return unpack('H*', $bytes)[1]; } /** * @param int $offset * @param int $numBytes * @param bool $str * @return array */ public function readc(int $offset, int $numBytes, bool $str = true) { $this->seek($offset); $bytes = null; for ($i = $this->offset; $i < $this->offset + $numBytes; $i++) { $str ? $bytes .= $this->data[$i] : $bytes[] = $this->data[$i]; } return unpack('C*', $bytes); } /** * @return bool */ public function rewind(): bool { $this->offset = 0; return true; } /** * @param int $offset * @param int $byte * @return void */ public function writeByte(int $offset, int $byte) { $this->data[$offset] = pack('C', $byte); } /** * @param int $offset * @param string $bytes * @return false|void */ public function writeBytes(int $offset, string $bytes) { if ($offset < 0 || $offset > strlen($this->data) || $bytes == '') return false; $_bytes = str_split($bytes, 2); foreach ($_bytes as $k => $byte) { $pos = $offset + $k; $this->data[$pos] = pack('H*', $byte); } } /** * @param int $offset * @param string $bytes * @return false|void */ public function insertBytes(int $offset, string $bytes) { if ($offset < 0 || $offset > strlen($this->data) || $bytes == '') return false; $data = bin2hex($this->data); // convert to hex bytes string $newData = substr_replace($data, $bytes, $offset, 0); $this->data = hex2bin($newData); } /** * @return false|string */ public function getData() { return $this->data ? $this->data : false; } /** * @param $data * @return void */ public function setData($data){ $this->data = $data; } /** * @return int */ public function getOffset(): int { return $this->offset; } /** * @param string $str * @return bool */ public function isHexString(string $str): bool { if (strlen($str) % 2 == 0 && (ctype_xdigit($str))) { return true; } return false; } /** * @param $input * @return string */ public function toBits($input): string { $output = ''; if ($this->isHexString($input)) { foreach (str_split($input, 2) as $byte) { $output .= (strrev(str_pad(decbin(hexdec($byte)), 8, 0, STR_PAD_LEFT))); } return $output; } else if (is_string($input)) { foreach (str_split($input) as $i) { $output .= strrev(str_pad(decbin(ord($i)), 8, 0, STR_PAD_LEFT)); } return $output; } else if (is_int($input)) { return strrev(str_pad(decbin($input), 8, 0, STR_PAD_LEFT)); } else if (is_array($input)) { foreach ($input as $i) { $output .= $this->tobits($i); } return $output; } } /** * @param string $bits * @return string */ public function toBytesR(string $bits) : string { $bytes = ''; foreach (str_split($bits, 8) as $byteString) { $bytes .= strtoupper(str_pad(dechex(bindec(($byteString))), 2, 0, STR_PAD_LEFT)); } return $bytes; } /** * @param string $bits * @return string */ public function toBytes(string $bits) : string { foreach (str_split($bits, 8) as $byteString) { $bytes .= strtoupper(str_pad(dechex(bindec(strrev($byteString))), 2, 0, STR_PAD_LEFT)); } return $bytes; } /** * @param string $bits * @return string */ public function bitsToHexString(string $bits): string { $bytes = ''; foreach (str_split($bits, 8) as $byte) { $bytes .= (str_pad(dechex((bindec(strrev($byte)))), 2, 0, STR_PAD_LEFT)); } return $bytes; } /** * @param string $bits * @return array */ public function bitsToHexArray(string $bits): array { $bytes = []; foreach (str_split($bits, 8) as $byte) { $bytes[] = (str_pad(dechex((bindec(strrev($byte)))), 2, 0, STR_PAD_LEFT)); } return $bytes; } /** * @param string $bits * @return array */ public function bitsToIntArray(string $bits): array { $bytes = []; foreach (str_split($bits, 8) as $byte) { $bytes[] = (int) (str_pad(dechex((bindec(strrev($byte)))), 2, 0, STR_PAD_LEFT)); } return $bytes; } /** * @param int $byte * @param int $pos * @param bool $bit * @return int */ public function setBit(int $byte, int $pos, bool $bit) { return ($bit ? ($byte | (1 << $pos)) : ($byte & ~(1 << $pos)) ); } /** * @param int $byte * @param int $pos * @return int */ public function getBit(int $byte, int $pos): int { return intval(($byte & (1 << $pos)) != 0); } }