What is Unpack's "binary string" - php

I'm trying to the unpack function. The PHP documentation says
Unpacks from a binary string into an
array according to the given format.
Does the string passed have to be a binary string? and what exactly is a binary string?

A binary string just means data that is in it's base binary format. The data it's self is being displayed as a string to you if you where to echo it, but it would be meaningless without applying it's correct structure to it. So for example a number would not look like a number, because it's in binary. While the data is there, it has to be parsed as a number for it to be readable as a number otherwise it could look like 'abcd'.

if you read down slightly further you will see examples of what binary strings look like
$binarydata = "\x32\x42\x00\xa0";
Also the description of the method clearly says Unpacks from a binary string, so yes it requires a binary string.
more information on binary

Related

How to fully decode a base64 string in PHP?

I'm trying to implement the Google Safebrowsing update API v4 in PHP.
But I can't figure how to correctly decode the rawHashes.
(The rawHashes are 4-bytes-truncated sha256 hashes and then concatenated).
I am trying the native base64_decode of PHP but I can't fully decode the string, and I don't know what the next step is.
According to the API documentation here's how the rawhashes are encoded :
string (bytes format)
The hashes, in binary format, concatenated into one long string. Hashes are sorted in lexicographic order. For JSON API users, hashes are base64-encoded.
A base64-encoded string.
I an very simply decoding the string like so:
$decoded = base64_decode($rawHashes);
The base64 encoded string look like this:
"AAAIYAAAC90AABOxAAAjDgAALZIAAEbKAABIHwAA..."
And the base64 decoded string look like this:
b"\x00\x00\x08`\x00\x00\vÝ\x00\x00\x13±\x00\x00#\x0E\x00\x00-’\x00\x00FÊ\x00\x00H\x1F\x00\x00^\x06\x00\x00bF\x00\x00h²"
As you can see something is not right and I must have missed a step but I can't figure which one.
As Mjh said in the discussion nothing is wrong about base64_decode and nothing else is needed.
Nothing's wrong. You just aren't reading carefully. Here, read what it says: The hashes, in binary format. It says binary format. After decoding, you got binary representation of the data. Using bin2hex should return a human-readable hash. $hash = bin2hex(base64_decode($your_encoded_hash)); - Mjh
The decoded string was looking weird as it is binary data (Raw SHA256 hash) although it is totally correct. To get the hashes in a more convenient encoding it's possible to convert the binary represented data to hex represented data with the php function bin2hex
$hash = bin2hex(base64_decode($your_encoded_hash));
From what I know of base64_decode, it just works. Something must be wrong in your $rawHashes string. If you have line breaks in your string, you need to get rid of them by replacing them with an empty string. The hash that base64_decode needs should be one long line of base64 encoded string. It is not uncommon to receive a hash that is broken into multiple lines.
Try this ...
$decoded = base64_decode(str_replace(PHP_EOL, "", $rawHashes));

How to write "pseudo" binary into file using php?

I have a string containing something like "01001010" and I want to write it into a file using binary. In other words, what's inside that file is not the chars 0/1, but in binary format.
How can I make that?
So you mean you want to convert a string of 0s and 1s (eg $bitString = '01010101...';) into binary data (0x55...), and then write that to a file, you need to do this in two steps.
First, convert your string of zeros and ones into binary - see Converting string of 1s and 0s into binary value, then compress afterwards ,PHP
Note that strings in PHP can store binary data.
Then just write the output to a file, eg using file_put_contents().

Get Ruby's OpenSSL::HMAC.hexdigest() to output the same as PHP's hash_hmac()

I'm trying to use the API of a web service provider. They don't have an example in Ruby, but they do have one for PHP, and I'm trying to interpret between the two. The API examples always use "true" on PHP's hash_hmac() call, which produces a binary output. The difference seems to be that Ruby's OpenSSL::HMAC.hexdigest() function always returns text. (If I change the PHP call to "false" they return the same value.) Does anyone know of a way to "encode" the text returned from OpenSSL::HMAC.hexdigest() to get the same thing as returned from a hash_hmac('sha256', $text, $key, true)?
Use OpenSSL::HMAC.digest to get the binary output.
You'll need to convert each pair of hex digits into a byte with the same value. I don't know any Ruby, but this is similar to how it would be handled in PHP.
First, take your string of hex digits and split them into an array. Each element in the array should be two characters long. Convert each element from a string of two hex bytes to an integer. It looks like you can do this by calling the hex method on each string.
Next, call pack on the converted array using the parameter c*, to convert each integer into a one-byte character. You should get the correct string of bytes as the result.

In PHP what does it mean by a function being binary-safe?

In PHP what does it mean by a function being binary-safe ?
What makes them special and where are they typically used ?
It means the function will work correctly when you pass it arbitrary binary data (i.e. strings containing non-ASCII bytes and/or null bytes).
For example, a non-binary-safe function might be based on a C function which expects null-terminated strings, so if the string contains a null character, the function would ignore anything after it.
This is relevant because PHP does not cleanly separate string and binary data.
The other users already mentioned what binary safe means in general.
In PHP, the meaning is more specific, referring only to what Michael gives as an example.
All strings in PHP have a length associated, which are the number of bytes that compose it. When a function manipulates a string, it can either:
Rely on that length meta-data.
Rely on the string being null-terminated, i.e., that after the data that is actually part of the string, a byte with value 0 will appear.
It's also true that all string PHP variables manipulated by the engine are also null-terminated. The problem with functions that rely on 2., is that, if the string itself contains a byte with value 0, the function that's manipulating it will think the string has ended at that point and will ignore everything after that.
For instance, if PHP's strlen function worked like C standard library strlen, the result here would be wrong:
$str = "abc\x00abc";
echo strlen($str); //gives 7, not 3!
More examples:
<?php
$string1 = "Hello";
$string2 = "Hello\x00World";
// This function is NOT ! binary safe
echo strcoll($string1, $string2); // gives 0, strings are equal.
// This function is binary safe
echo strcmp($string1, $string2); // gives <0, $string1 is less than $string2.
?>
\x indicates hexadecimal notation. See: PHP strings
0x00 = NULL
0x04 = EOT (End of transmission)
ASCII table to see ASCII char list

PHP: Very simple Encode/Decode string

Is there any PHP function that encodes a string to a int value, which later I can decode it back to a string without any key?
Sure, you can convert strings to numbers and vice versa. Consider:
$a = "" + 1
gettype($a) // integer
$b = "$a"
gettype($b) // string
You can also do type casting with settype().
If I misunderstood you and you want to encode arbitrary strings, consider using base64_encode() and bas64_decode(). If you want to convert the base 64 string representation to a base 10 integer, simply use base_convert().
And int has 4 or 8 bytes depending on the platform, and each character in a string is one byte (or more depending on encoding). So, you can only encode very small strings to integers, which basically makes the answer to your question: no.
What do you want to accomplish?
I would suspect not, since there are far more possible string combinations than integers within the MAX_INT.
Does it have to be an integer?
i'm convinced that what you think you want to do is not really what you want to do. :-) this just sounds like a silly idea. As another user has asked before:) what do you need this for? What are your intentions?
Well now that you mentioned that numbers and a-z letter are acceptable, then I have one suggestion, you could loop through the individual letters' ordinal value and display that as a two-digit hexadecimal. You can then convert these hexadecimals back to the ordinal values of the individual characters. Don't know what kind of characters are you about to encode, possibly you will need to use 4-characters per letter (e.g. String Peter would become 00700065007400650072 ) Well... have fun with that, I still don't really see the rationale for doing what you're doing.
op through the individual letters' ordinal value and display that as a two-digit hexadecimal. You can then convert these hexadecimals back to the ordinal values of the individual characters. Don't know what kind of characters are you about to encode, possibly you will need to use 4-characters per letter (e.g. String Peter would become 00700065007400650072 ) Well... have fun with that, I still don't really see the
There is no function for PHP but I recently wrote a class to encrypt and decrypt a string in PHP. You can look at it at: https://github.com/Lars-/PHP-Security-class

Categories