Преобразование строки C (\ 0 прекращено) в строку PHP - PullRequest
4 голосов
/ 27 октября 2010

PHP - один из тех языков, которые я периодически использую, но обычно мне приходится стирать паутину, когда я снова его использую.То же самое относится и к этой неделе, когда я перенесу некоторый C-код на PHP.При этом используется много AES-шифрования и хэширования SHA256 - пока все работает нормально.Однако расшифрованные строки выходят в форме «C» - то есть заканчиваются нулевым байтом, за которым следуют байты заполнения «мусора».

В настоящее время я «обрезаю» эти строки в стиле C до формы PHP следующим образом:1003 *

$iv = strpos( $hashsalt8, "\0");
if ($iv)
   $hashsalt8 = substr( $hashsalt8, 0, $iv );

Кажется скучным и что вместо этого должен быть вызов функции из одной строки, но я не могу его найти?

Примечание: хотя в этом случае имя "соль хеша"подразумевает, что я могу знать длину исходной строки, в общем случае это неизвестно.Очевидно, что доступно однострочное решение с использованием substr(), если длина известна априори.

Ответы [ 3 ]

9 голосов
/ 27 октября 2010

Использование strstr:

$hashsalt8 = strstr($hashsalt8, "\0", TRUE);

Более уродливое решение для версий менее 5.3.0 (где третий параметр недоступен) использует strrev, substr и strrchr функции вместо:

$hashsalt8 = strrev(substr(strrchr(strrev($hashsalt8), "\0"), 1));
2 голосов
/ 28 октября 2010

Функция strtok сделает это за один проход, а не за два:

$hashsalt8 = strtok($hashsalt8, "\0");

Однако, начиная с PHP 4.1.0, strtok не будет возвращать пустую строкуесли входная строка начинается с нулевого байта.Вы можете сделать следующее, чтобы обработать этот случай:

if ($hashsalt8[0] == "\0") {
  $hashsalt8 = '';
}
else {
  $hashsalt8 = strtok($hashsalt8, "\0");
}

Обратите внимание, что входная строка, начинающаяся с нулевого байта, также представляет ошибку в вашем текущем коде.В этом случае strpos вернет 0 и if ($iv) не удастся.

Вы должны использовать оператор !==, чтобы различать 0 и false:

$iv = strpos($hashsalt8, "\0");
if ($iv !== false) {
   $hashsalt8 = substr($hashsalt8, 0, $iv);
}
2 голосов
/ 27 октября 2010

Никогда не должно быть больше 32 байтов заполнения, верно?(из вашего комментария здесь)

Вы можете сделать что-то вроде этого:

preg_replace('/\x00.{0,32}$/', "", $hashsalt8);

Обратите внимание на одинарные кавычки вместо двойных, если вы используете двойные кавычки \x00кажется, ломает preg:)

...