I have an existing NodeJS lib whose hashed Buffer functionality I am trying to match in PHP (specifically the "AFTER" value below), but have so far failed. What is NodeJS doing to a Buffer internally such that it can be hashed and returned as a new Buffer?
...
let concatValue = isHex(currentbranchOps[o].r) ? Buffer.from(currentbranchOps[o].r, 'hex') : Buffer.from(currentbranchOps[o].r, 'utf8')
currentHashValue = Buffer.concat([currentHashValue, concatValue])
console.log('BEFORE: ', currentHashValue); // Uint8Array(76) [110, 111, 100, 101......]
currentHashValue = crypto.createHash('sha256').update(currentHashValue).digest()
console.log('AFTER: ', currentHashValue); // Uint8Array(32) [123, 67, 203, 88......]
...
Given that only stringy types can be hashed, how is Node arriving at the "AFTER" value above in the form of another Buffer?
In PHP I have tried:
hash('sha256', pack('H*', implode('', [110, 111, 100, 101......] )))
hash('sha256', pack('c*', implode('', [110, 111, 100, 101......] )))
I also wrote a routine that gives me a digest of the array as a string, and then hashing the result (and various permutations thereof), without being able to match exactly what Node gives me in the "AFTER" block.
function buffer_digest_from(array $dec) : string
{
$hex = '';
foreach($dec as $int) {
// Left pad single hex values with zeroes, to match chainpoint hashes
$hex .= str_pad(dechex($int), 2, '0', STR_PAD_LEFT);
}
return $hex;
}
hash('sha256', pack('H*', buffer_digest_from([110, 111, 100, 101......] )));
hash('sha256', pack('c*', buffer_digest_from([110, 111, 100, 101......] )));
hash('sha256', buffer_digest_from([110, 111, 100, 101......] ));
I realise of course that languages vary in their implementations, but if all I wish to do is manipulate integers, then there should be some way to arrive at the same solution, regardless of implementation.
Many thanks for reading.
I think this question might stem from a misunderstanding of what Node.js buffers are. They are really just a sequence of bytes. The default way to output them in the console and interact with them looks like an array of numbers.
PHP also has a similar data type that stores lists of bytes, but it's interface looks less like an array. It's actually the humble string
.
PHP's string is not like Javascript's string. Javascript's string is more like a 'series of characters', but PHP's string is just a list of bytes.
So if you have a (PHP) array like:
$input = [110, 111, 100, 101.....];
To convert that into a string, you would actually just do:
$buffer = '';
foreach($input as $byte) {
$buffer .= chr($byte);
}
The reason Node.js Buffer exist, is because Javascript didn't originally have a 'series of bytes' data structure, and you can't really use javascript's string to store any list of bytes.
So even though their interfaces are different, the following 3 data types are more or less equivalent:
string
Buffer
char
(there is no native C string type)PHP was going to have a data structure similar to Javascript's string in PHP 6, but PHP 6 was canned.