data = $data; // Assign the provided data to the internal property "data" } /** * Skips a specified number of bytes. * * @param int $numBytes The number of bytes to skip. * @return bool Returns true on success, false otherwise. */ public function skip(int $numBytes): bool { if ($numBytes < 0 || $numBytes > strlen($this->data)) { // Check if the specified number of bytes is within the valid range return false; // Return false if the number of bytes is invalid } $this->offset += $numBytes; // Increment the internal offset by the specified number of bytes return true; // Return true to indicate a successful skip operation } /** * Moves the offset position to a specified position. * * @param int $pos The new offset position. * @return bool Returns true if the offset position is valid, false otherwise. */ public function seek(int $pos): bool { if ($pos < 0 || $pos > strlen($this->data)) { // Check if the specified position is within the valid range return false; // Return false if the position is invalid } $this->offset = $pos; // Set the internal offset to the specified position return true; // Return true to indicate a successful seek operation } /** * Reads a specified number of bytes from the current offset position. * * @param int $offset The offset position to start reading from. * @param int $numBytes The number of bytes to read. * @param bool $str Indicates whether to return the result as a string (default) or an array. * @return string|array The read bytes. */ public function read(int $offset, int $numBytes, bool $str = true) { $this->seek($offset); // Set the internal offset to the specified position $bytes = null; // Initialize a variable to store the read bytes // Loop through the specified number of bytes for ($i = $this->offset; $i < $this->offset + $numBytes; $i++) { // Depending on the $str parameter, concatenate the byte to $bytes as a string or add it to $bytes array $str ? $bytes .= $this->data[$i] : $bytes[] = $this->data[$i]; } return $bytes; // Return the read bytes as either a string or an array } /** * Reads a specified number of bytes from the current offset position and returns them as a hex string. * * @param int $offset The offset position to start reading from. * @param int $numBytes The number of bytes to read. * @param bool $str Indicates whether to return the result as a string (default) or an array. * @return string The read bytes as a hex string. */ public function readh(int $offset, int $numBytes, bool $str = true) { $this->seek($offset); // Set the internal offset to the specified position $bytes = null; // Initialize a variable to store the read bytes // Loop through the specified number of bytes for ($i = $this->offset; $i < $this->offset + $numBytes; $i++) { // Depending on the $str parameter, concatenate the byte to $bytes as a string or add it to $bytes array $str ? $bytes .= $this->data[$i] : $bytes[] = $this->data[$i]; } return unpack('H*', $bytes)[1]; // Unpack the bytes into a hexadecimal string and return it } /** * Reads a specified number of bytes from the current offset position and returns them as an array of integers. * * @param int $offset The offset position to start reading from. * @param int $numBytes The number of bytes to read. * @param bool $str Indicates whether to return the result as a string (default) or an array. * @return array The read bytes as an array of integers. */ public function readc(int $offset, int $numBytes, bool $str = true) { $this->seek($offset); // Set the internal offset to the specified position $bytes = null; // Initialize a variable to store the read bytes // Loop through the specified number of bytes for ($i = $this->offset; $i < $this->offset + $numBytes; $i++) { // Depending on the $str parameter, concatenate the byte to $bytes as a string or add it to $bytes array $str ? $bytes .= $this->data[$i] : $bytes[] = $this->data[$i]; } return unpack('C*', $bytes); // Unpack the bytes into an array of unsigned characters } /** * Rewinds the offset position to the beginning. * * @return bool Returns true on success. */ public function rewind(): bool { $this->offset = 0; // Set the offset property to 0, indicating the start position return true; // Return true to indicate that the rewind operation was successful } /** * Writes a byte at the specified offset position. * * @param int $offset The offset position to write the byte. * @param int $byte The byte value to write. * @return void */ public function writeByte(int $offset, int $byte) { $this->data[$offset] = pack('C', $byte); } /** * Writes multiple bytes starting from the specified offset position. * * @param int $offset The offset position to start writing from. * @param string $bytes The bytes to write. * @return false|void Returns false on failure or void on success. */ public function writeBytes(int $offset, string $bytes) { if ($offset < 0 || $offset > strlen($this->data) || $bytes == '') { return false; // Return false if the offset is invalid or the bytes string is empty } $_bytes = str_split($bytes, 2); // Split the bytes string into an array of two-character chunks foreach ($_bytes as $k => $byte) { $pos = $offset + $k; // Calculate the position in the data to write the byte $this->data[$pos] = pack('H*', $byte); // Pack the hexadecimal byte into binary format and write it at the specified position } } /** * Inserts bytes at the specified offset position. * * @param int $offset The offset position to insert the bytes. * @param string $bytes The bytes to insert. * @return false|void Returns false on failure or void on success. */ public function insertBytes(int $offset, string $bytes) { if ($offset < 0 || $offset > strlen($this->data) || $bytes == '') { return false; // Return false if the offset is invalid or the bytes string is empty } $data = bin2hex($this->data); // Convert the binary data to a hexadecimal string $newData = substr_replace($data, $bytes, $offset, 0); // Insert the new bytes at the specified offset in the hexadecimal string $this->data = hex2bin($newData); // Convert the modified hexadecimal string back to binary data and update the 'data' property } /** * Returns the byte data. * * @return false|string Returns the byte data on success, or false if no data is set. */ public function getData() { return $this->data ? $this->data : false; // Return the value of the 'data' property if it exists, otherwise return false } /** * Sets the byte data. * * @param $data The byte data to set. * @return void */ public function setData($data) { $this->data = $data; // Set the value of the 'data' property to the provided data } /** * Returns the current offset position. * * @return int The current offset position. */ public function getOffset(): int { return $this->offset; // Return the value of the 'offset' property } /** * Checks if a string is a valid hexadecimal string. * * @param string $str The string to check. * @return bool Returns true if the string is a valid hexadecimal string, false otherwise. */ public function isHexString(string $str): bool { // Check if the length of the string is even and if all characters are hexadecimal using ctype_xdigit function if (strlen($str) % 2 == 0 && ctype_xdigit($str)) { return true; // Return true if the string is a valid hexadecimal string } return false; // Return false if the string is not a valid hexadecimal string } /** * Converts input to a string of bits. * * @param mixed $input The input to convert. * @return string The converted string of bits. */ public function toBits($input): string { $output = ''; // Initialize an empty string to store the resulting bits // Check if the input is a hexadecimal string if ($this->isHexString($input)) { // Convert each byte of the hexadecimal string to binary and concatenate the bits to the output // Split the hexadecimal string into an array of bytes (2 characters per byte) foreach (str_split($input, 2) as $byte) { // Convert the byte from hexadecimal to decimal using `hexdec` function, // then convert the decimal to binary using `decbin` function, // reverse the resulting binary string using `strrev` function, // and pad the binary string with leading zeros to make it 8 bits long using `str_pad` function. // Finally, concatenate the resulting bits to the output string. $output .= (strrev(str_pad(decbin(hexdec($byte)), 8, 0, STR_PAD_LEFT))); } return $output; // Return the resulting bits } else if (is_string($input)) { // Convert each character of the string to binary and concatenate the bits to the output // Split the string into an array of characters foreach (str_split($input) as $i) { // Convert the character to its ASCII value using `ord` function, // then convert the ASCII value to binary using `decbin` function, // reverse the resulting binary string using `strrev` function, // and pad the binary string with leading zeros to make it 8 bits long using `str_pad` function. // Finally, concatenate the resulting bits to the output string. $output .= strrev(str_pad(decbin(ord($i)), 8, 0, STR_PAD_LEFT)); } return $output; // Return the resulting bits } else if (is_int($input)) { // Convert the integer to binary and return the resulting bits // Convert the integer to binary using `decbin` function, // reverse the resulting binary string using `strrev` function, // and pad the binary string with leading zeros to make it 8 bits long using `str_pad` function. // Finally, return the resulting bits. return strrev(str_pad(decbin($input), 8, 0, STR_PAD_LEFT)); } else if (is_array($input)) { // If the input is an array, recursively call the `toBits` function for each element and concatenate the bits to the output // Iterate over each element in the input array foreach ($input as $i) { // Recursively call the `toBits` function for the current element, // and concatenate the resulting bits to the output string. $output .= $this->toBits($i); } return $output; // Return the resulting bits } } /** * Converts a string of bits to bytes (reversing the bit order). * * @param string $bits The string of bits to convert. * @return string The converted bytes. */ public function toBytesR(string $bits): string { $bytes = ''; // Initialize an empty string to store the resulting bytes // Split the bits string into an array of byte-sized chunks (8 bits per chunk) foreach (str_split($bits, 8) as $byteString) { // Convert each byte-sized chunk from binary to decimal using `bindec` function, // then convert the decimal to hexadecimal using `dechex` function, // and pad the resulting hexadecimal string with leading zeros to make it 2 characters long using `str_pad` function. // Finally, concatenate the resulting byte to the bytes string. $bytes .= strtoupper(str_pad(dechex(bindec($byteString)), 2, 0, STR_PAD_LEFT)); } return $bytes; // Return the resulting bytes } /** * Converts a string of bits to bytes. * * @param string $bits The string of bits to convert. * @return string The converted bytes. */ public function toBytes(string $bits): string { $bytes = ''; // Initialize an empty string to store the resulting bytes // Split the bits string into an array of byte-sized chunks (8 bits per chunk) foreach (str_split($bits, 8) as $byteString) { // Reverse the order of bits within each byte-sized chunk using `strrev` function, // then convert the reversed binary string to decimal using `bindec` function, // then convert the decimal to hexadecimal using `dechex` function, // and pad the resulting hexadecimal string with leading zeros to make it 2 characters long using `str_pad` function. // Finally, concatenate the resulting byte to the bytes string. $bytes .= strtoupper(str_pad(dechex(bindec(strrev($byteString))), 2, 0, STR_PAD_LEFT)); } return $bytes; // Return the resulting bytes } /** * Converts a string of bits to a hexadecimal string. * * @param string $bits The string of bits to convert. * @return string The converted hexadecimal string. */ public function bitsToHexString(string $bits): string { $bytes = ''; // Initialize an empty string to store the resulting hexadecimal bytes // Split the bits string into an array of byte-sized chunks (8 bits per chunk) foreach (str_split($bits, 8) as $byte) { // Reverse the order of bits within each byte-sized chunk using `strrev` function, // then convert the reversed binary string to decimal using `bindec` function, // then convert the decimal to hexadecimal using `dechex` function, // and pad the resulting hexadecimal string with leading zeros to make it 2 characters long using `str_pad` function. // Finally, concatenate the resulting hexadecimal byte to the bytes string. $bytes .= (str_pad(dechex(bindec(strrev($byte))), 2, 0, STR_PAD_LEFT)); } return $bytes; // Return the resulting hexadecimal bytes } /** * Converts a string of bits to an array of hexadecimal values. * * @param string $bits The string of bits to convert. * @return array The converted array of hexadecimal values. */ public function bitsToHexArray(string $bits): array { $bytes = []; // Initialize an empty array to store the resulting hexadecimal bytes // Split the bits string into an array of byte-sized chunks (8 bits per chunk) foreach (str_split($bits, 8) as $byte) { // Reverse the order of bits within each byte-sized chunk using `strrev` function, // then convert the reversed binary string to decimal using `bindec` function, // then convert the decimal to hexadecimal using `dechex` function, // and pad the resulting hexadecimal string with leading zeros to make it 2 characters long using `str_pad` function. // Finally, add the resulting hexadecimal byte to the bytes array. $bytes[] = (str_pad(dechex(bindec(strrev($byte))), 2, 0, STR_PAD_LEFT)); } return $bytes; // Return the resulting array of hexadecimal bytes } }