2010-12-31 4 views
14

В PHP, если у вас есть переменная с двоичными данными, как вы получаете конкретные байты из данных? Например, если у меня есть данные длиной 30 байтов, как я могу получить первые 8 байтов?Байт манипуляции в PHP

Прямо сейчас, я рассматривая его как строку, используя substr() функцию:

$data = //... 
$first8Bytes = substr($data, 0, 8); 

Безопасно ли использовать substr с бинарными данными?

Или есть другие функции, которые я должен использовать?

+0

Вы имеете в виду, если это двоичные данные? – BoltClock

+0

@BoltClock Да, это правильно. – Michael

ответ

6

Как правило, все строковые функции в PHP безопасны для использования с необработанными байтами. Проблема, которая в основном возникает, равна null-байтам, но только для файловых систем: http://php.net/manual/en/security.filesystem.nullbytes.php

Ваш substr() отлично подходит для использования с двоичными строками. Некоторые другие функции, такие как strtok и ereg, однако, интерфейс к C, где символ «\ 0» становится проблемой.

+0

Спасибо, единственная строка, с которой я использую это, - 'substr'. Что делать, если PHP настроен на использование UTF-16 для своих строк, где каждый символ составляет> 1 байт? – Michael

+0

@MichaelAngstadt. Я бы счел, что неправильная конфигурация и не заботясь. Для чего стоит 'mb_substr (" \ 0 \ 0 \ 0 \ 0 ", 0, 2)', похоже, работает для UTF-8. Для UTF-16, однако, он возвращается в два раза больше, как и ожидалось. Так что более вероятно, что вы потерпите неудачу - это ваша последующая обработка в этих условиях. – mario

+0

О, так что 'substr' будет ВСЕГДА считать 1 символ 1 байт, а' mb_substr' учитывает кодировку символов? Похоже, я был бы безопасен, используя 'substr', независимо от кодировки символов. – Michael

3

Звучит хорошо, так как PHP имеет дело строки (внутри) «как» C полукокса * (1 байт = 1char)

С другой стороны, это может быть нарушена, если строка в кодировке Unicode (2 байта = 1 символ)

нба: Вы также можете играть с колодой() и распаковать() для управления «Реал» байт

+0

@Stef Спасибо, да, это одна вещь, о которой я беспокоился ... что, если PHP настроен на поддержку чего-то вроде UTF-16 для своих строк? – Michael

+1

@Michael: Я бы поспорить на нем. – BoltClock

+0

Да, я тоже, но кто знает, может быть в 2011 году знаменитый php 6.0;) – Stef

9

Если mbstring extension установлен и mbstring overloading включен, то с помощью substr может дать вам неприятность. Перегрузка Mbstring приведет к тому, что mb_substr будет автоматически вызываться каждый раз, когда вызывается substr (если mbstring установлен, а перегрузка mbstring равна отключена, то substr будет правильно извлекать байты). Следующий код будет использовать mb_substr, если mbstring установлен и substr, если это не так. Используется кодировка символов «8 бит», которая обрабатывает каждый символ как 1 байт и игнорирует нулевые терминаторы ('\ 0').

if (function_exists('mb_substr')) { 
    $bytes = mb_substr($string, 0, 8, '8bit'); 
} else { 
    $bytes = substr($string, 0, 8); 
} 

Thanks to ircmaxell

+0

Прошу прояснить, что вы подразумеваете под «игнорируете нулевые терминаторы». Это было бы нарушением транзакции для манипулирования данными, если бы это было правдой. Я сделал несколько тестов, и я не вижу, чтобы он игнорировал символы \ 0. (Править) О, я просто прочитал чат. Вы имеете в виду «ascii». Поэтому использование «8bit» ** не ** игнорирует нулевые терминаторы. – Phil

Смежные вопросы