Read bin file php

Работа с бинарными данными в php

PHP как язык плохо подходит для работы бинарными данными напрямую. Но иногда приложения должны взаимодействовать по таким протоколам, где размер пакетов очень важен или родным форматом данных для какого-то приложения, который никем в красивый json или xml не переводится.

Целые типы данных

Напоминаю какие типы данных есть в Си, на котором основан php

Тип Размер памяти Значений всего
char 1 байт = 8 бит 256
int 2 байт = 16 бит 2^16=65536
short 2 байта
long 4 байта = 32 бита 4294967295

Char при этом используется универсально согласно ASCII табличке как в качестве явного кодирования текста, так и вспомогательными маркерами. Про float я умолчу, ибо мне не понадобилось.

Нотация

Если с бинарными данными не работать, то можно и забыть основы языка. С целыми числами на основании 10 всё понятно, но обычно значения длинных данных в них не пишут. Это объясняет табличку выше.

  • Бинарная, например 0b1011
  • Восьмеричная, например 0123
  • Шестнадцатиричная, например 0xF560B1A9

Кроме этого, если вы переписываетесь с коллегами которые пишут на си, то они могут обозначать приставками или окончаниями

  • Unsigned int 14u
  • Long double или long int. Например 1.2l или 1L — фиг поймёшь, это единица или long
  • Float (с плавающей запятой) 1.3f или 1.3F

Итого, у нас char a будет хранить значение от -128 до 127.. ну или 256 если это extended ASCII. Отлично. Теперь как это использовать в php?

Порядок битов

Честно, для меня было откровением что порядок в данных имеет значение. Я привык что 123 уже подразумевает где сотни, десятки и единицы, но для компьютера ведь всё равно. Конечно одно дело порядок написания для человека.. но тут другое — порядок записи байтов в зависимости от адреса. И больше всего удивительно что архитектуры на уровне работы с памятью разделились — x86 на стороне little endian, а за big endian SPARC и прочие. Поэтому если вы интегрируете разные архитектуры с бинарным форматом данных — договоритесь которая система будет работать.

Операции

1. Бинарное чтение файла — fopen(«binaryfile»,»b»);

2. Битовые маски — популярный метод хранить много булевых значений в одной переменной и включать/проверять с помощью AND/OR операций. Если вы когда либо выполняли chmod 755, то уже включали эти флажки на привилий.

3. Побитовые сдвиги — помогают работать с битовыми масками и с битами в вообще

$b = $a >> 2 ; — сдвиг битов на две позиции вправо, тут может пригодится константа PHP_INT_SIZE
$b = 8 >> 3 ; // 1

4. Cyclic redundancy check

Проверка данных с помощью контрольных сумм увы для меня осталась за пределами понимания. Важно знать что биты суммируются, и что полиномы бывают разные. Соответсвенно алгоритмы тоже бывают разные и как правило неограничивается функцией crc32(). Гляньте на мою коллекцию и онлайн валидатор .

Читайте также:  In python everything is an object

Вот пример самого короткого кода для CRC16 CCITT

function crc16_ССITT($data) < $crc = 0xFFFF; for($i = 0; $i < strlen($data); $i++) < $x = (($crc >> 8) ^ ord($data[$i])) & 0xFF; $x ^= $x >> 4; $crc = (($crc 8) ^ ($x 12) ^ ($x 5) ^ $x) & 0xFFFF; > return $crc; >

5. Упаковка

Если вы обычную переменную в php начнёте сохранять в файл, то она наверняка не будет оптимальной. А если таких однородных данных много — то тем более имеет смысл создать более компактную версию.

Например, если вы хотите число 250 записать в один байт как char-тип, вместо того что-бы писать «строкой» в три символа, как то будет делать php по умолчанию, пишем:

Первый аргумент это формат данных по длине. Если все данные char-типа, то можно написать c* как в регулярных выражениях, получить повторение типа. Можно написать c4, что будет аналогично cccc (четыре повторения данных char-типа)

  • a — строка, свободные места в поле заполняются символом с кодом 0
  • A — строка, свободные места заполняются пробелами
  • h — шестнадцатеричная строка, младшие разряды в начале (little endian)
  • H — шестнадцатеричная строка, старшие разряды в начале (big endian)
  • c — 1 байт (signed char)
  • C — 1 байт (unsigned char)
  • x — символ с нулевым кодом
  • X — возврат назад на 1 байт
  • @ — заполнение нулевым кодом до заданной абсолютной позиции
  • s — short (16 bit)
  • S — unsigned short
  • n — short (big endian)
  • v — unsigned short (little endian)
  • i — integer (размер и порядок байтов определяется архитектурой)
  • I — unsigned integer
  • l — знаковое длинное целое (32 бита, порядок знаков определяется архитектурой)
  • L — беззнаковое длинное целое
  • N — беззнаковое длинное целое (32 бита, старшие разряды в конце)
  • V — беззнаковое целое (32 бита, младшие разряды в конце)

Сам не проверял, но говорят что unsigned int получить не так то просто

6. Распаковка

Для раскодирования используется unpack() с аналогичным форматом типов данных, только теперь можно добавлять названия ключей для результатов ассоциативного массива
unpack ( «cmessageid/Vtimestamp» , pack ( «H*» ,FFFF));

Заметьте что pack я тут использую вместо hex2bin, которая недоступна для версий php менее 5.4

7. Конвертирование

base_convert — конвертирование строковых представлений чисел из любого основания в другое (скажем 16 в 2)
bindec, decbin — конвертирование 5 двоичных и десятичных данных
octdec, decoct — конвертирование 8 десятичных и восьмеричных данных
hexdec, dechex — конвертирование 16 десятичных и шестнадцатиричных данных
ord, chr — конвертирование 256 десятичных и символьных (ascii) данных

base64_encode, base64_decode — конвертирование 256 данных, но в отличие от предыдущих форматов, данные одного значения не кодируются в 6 битах что-бы получить 64 значения, а по прежнему в 8 битах — остальные символы просто не используются.. Из-за этого формат менее эффективен в хранении, но для человека в виде текста более компактен чем нули, единицы или hex.

Читайте также:  Panel

Отличительная и неприятная особенность, конечно в том что каждая из функций конвертирует данные со строго определённым размером данных. Обычно же у нас есть какой-то пакет данных. Их можно проконвертировать в цикле с определённым шагом..

function str2bin($str, $mode=0, $visual_aid=true) < $out = false; for($a=0; $a < strlen($str); $a++) < $dec = ord(substr($str,$a,1)); $bin = ''; for($i=7; $i>=0; $i--) < if ( $dec >= pow(2, $i) ) < $bin .= "1"; $dec -= pow(2, $i); > else < $bin .= "0"; > > /* Default-mode */ if ( $mode == 0 ) $out .= $bin; /* Human-mode (easy to read) */ if ( $mode == 1 ) $out .= $bin . " "; /* Array-mode (easy to use) */ if ( $mode == 2 ) $out[$a] = $bin; if($visual_aid)< $out.=" "; > > return $out; > function str2dec($string, $visual_aid=true)< $hex=''; for ($i=0; $i < strlen($string); $i++) < $hex .= ord($string[$i]); if($visual_aid)< $hex.= "(".$string[$i].") "; > > return $hex; > function str2hex($string, $visual_aid=true)< $hex=''; for ($i=0; $i < strlen($string); $i++) < $hex .= dechex(ord($string[$i])); if($visual_aid)< $hex.= " "; > > return $hex; > function hex2str($hex)< $string=''; for ($i=0; $i < strlen($hex)-1; $i+=2) < $string .= chr(hexdec($hex[$i].$hex[$i+1])); > return $string; >

Читайте также

Простейший backdoor на php Backdoor — тайный ход, лазейка. Разумное человечество использовало всегда запасной случай что-бы не попасть впросак. К примеру те же замки,…

Сортировка матрицы на PHP Сортировку можно производить на стороне сервера в БД (самое логичное решение), но зачастую система не продумана заранее настолько и получается…

Cлучайные числа с плавающей точкой в PHP Стандартные библиотеки PHP умеют генерировать только целые случайные числа. Однако, возникают задачи где нужно не целое рандомное число с максимально…

Источник

Php – reading a bin file with php bin2hex function

I am trying to read a bin file that contains a lots of two 4-byte numbers in it, which I want to read and convert to hex numbers that is then going to be printed to the screen…. hopefully however I am having a little trouble getting my head around this one. this is what I have so far from reading examples and documentation..

I am 95% sure the error is in passing $handle over to tbin2hex.. but this being my first ever reading of a bin file I am slightly lost. the overall goal at some point will be to read the bin file into the database however I am just trying to figure out what this file looks like on screen.

Best Solution

EDIT: Also you should avoid using @ it can make debugging extremely frustrating.

Php – How to sanitize user input with PHP

It’s a common misconception that user input can be filtered. PHP even has a (now deprecated) «feature», called magic-quotes, that builds on this idea. It’s nonsense. Forget about filtering (or cleaning, or whatever people call it).

Читайте также:  Что дает html формате

What you should do, to avoid problems, is quite simple: whenever you embed a a piece of data within a foreign code, you must treat it according to the formatting rules of that code. But you must understand that such rules could be too complicated to try to follow them all manually. For example, in SQL, rules for strings, numbers and identifiers are all different. For your convenience, in most cases there is a dedicated tool for such an embedding. For example, when you need to use a PHP variable in the SQL query, you have to use a prepared statement, that will take care of all the proper formatting/treatment.

Another example is HTML: If you embed strings within HTML markup, you must escape it with htmlspecialchars . This means that every single echo or print statement should use htmlspecialchars .

A third example could be shell commands: If you are going to embed strings (such as arguments) to external commands, and call them with exec , then you must use escapeshellcmd and escapeshellarg .

Also, a very compelling example is JSON. The rules are so numerous and complicated that you would never be able to follow them all manually. That’s why you should never ever create a JSON string manually, but always use a dedicated function, json_encode() that will correctly format every bit of data.

The only case where you need to actively filter data, is if you’re accepting preformatted input. For example, if you let your users post HTML markup, that you plan to display on the site. However, you should be wise to avoid this at all cost, since no matter how well you filter it, it will always be a potential security hole.

Php – How to get a file extension in PHP

People from other scripting languages always think theirs is better because they have a built-in function to do that and not PHP (I am looking at Pythonistas right now :-)).

In fact, it does exist, but few people know it. Meet pathinfo() :

$ext = pathinfo($filename, PATHINFO_EXTENSION); 

This is fast and built-in. pathinfo() can give you other information, such as canonical path, depending on the constant you pass to it.

Remember that if you want to be able to deal with non ASCII characters, you need to set the locale first. E.G:

Also, note this doesn’t take into consideration the file content or mime-type, you only get the extension. But it’s what you asked for.

Lastly, note that this works only for a file path, not a URL resources path, which is covered using PARSE_URL.

Источник

Оцените статью