开发者

Converting a C (\0 terminated) string to a PHP string

开发者 https://www.devze.com 2023-01-22 10:13 出处:网络
PHP is one of those languages I use periodically, but usually have to dust the cobwebs off when I start using it again. The same applies this week whilst I port some C code to PHP. This uses a lot of

PHP is one of those languages I use periodically, but usually have to dust the cobwebs off when I start using it again. The same applies this week whilst I port some C code to PHP. This uses a lot of AES encryption and SHA256 hashing - all working fine so far. However, decrypted strings come out in "C" form - i.e. terminated with a zero byte followed by "garbage" padding bytes.

I currently "trim" these C-style strings to PHP form with the following:

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

Seems long-winded and that there should be a one line function call instead, but I can't find it?

Note: Although in this case the "hash salt" name implies I might know the length of the original string, this is unknown in the general case. Clearly a one line solution is available using substr() when the lengt开发者_JS百科h is known a priori.


Use strstr:

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

An uglier solution for versions less than 5.3.0 (where the third parameter isn't available) uses the strrev, substr and strrchr functions instead:

$hashsalt8 = strrev(substr(strrchr(strrev($hashsalt8), "\0"), 1));


There should never need to be more than 32 bytes of padding right? (from your comment here)

You might be able to do something like this:

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

Note the single quotes instead of the doubles, if you use the double quotes the \x00 seems to break preg :)


The strtok function will do it in one pass rather than two:

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

Since PHP 4.1.0, however, strtok will not return an empty string if the input string begins with a zero byte. You could do the following to handle that case:

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

Note that an input string beginning with a zero byte also exposes a bug in your current code. In that case, strpos will return 0 and if ($iv) will fail.

You should use the !== operator to differentiate between 0 and false:

$iv = strpos($hashsalt8, "\0");
if ($iv !== false) {
   $hashsalt8 = substr($hashsalt8, 0, $iv);
}
0

精彩评论

暂无评论...
验证码 换一张
取 消