Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Buffer to integer. Having trouble understanding this line of code

I'm looking for help in understanding this line of code in the npm moudle hash-index.

The purpose of this module is to be a function which returns the sha-1 hash of an input mod by the second argument you pass.

The specific function in this module that I don't understand is this one that takes a Buffer as input and returns an integer:

var toNumber = function (buf) {
  return buf.readUInt16BE(0) * 0xffffffff + buf.readUInt32BE(2)
}

I can't seem to figure out why those specific offsets of the buffer are chosen and what the purpose of multiplying by 0xffffffff is.

This module is really interesting to me and any help in understanding how it's converting buffers to integers would be greatly appreciated!

like image 899
Jekrb Avatar asked Oct 30 '22 13:10

Jekrb


1 Answers

It prints the first UINT32 (Unsigned Integer 32 bits) in the buffer.

First, it reads the first two bytes (UINT16) of the buffer, using Big Endian, then, it multiplies it by 0xFFFFFFFF.

Then, it reads the second four bytes (UINT32) in the buffer, and adds it to the multiplied number - resulting in a number constructed from the first 6 bytes of the buffer.

Example: Consider [Buffer BB AA CC CC DD ... ]

0xbb * 0xffffffff = 0xbaffffff45
0xbaffffff45 + 0xaaccccdd = 0xbbaacccc22

And regarding the offsets, it chose that way:

First time, it reads from byte 0 to byte 1 (coverts to type - UINT16)

second time, it reads from byte 2 to byte 5 (converts to type - UINT32)

So to sum it up, it constructs a number from the first 6 bytes of the buffer using big endian notation, and returns it to the calling function.

Hope that's answers your question.

Wikipedia's Big Endian entry

EDIT

As someone pointed in the comments, I was totally wrong about 0xFFFFFFFF being a left-shift of 32, it's just a number multiplication - I'm assuming it's some kind of inner protocol to calculate a correct legal buffer header that complies with what they expect.

EDIT 2

After looking on the function in the original context, I've come to this conclusion:

This function is a part of a hashing flow, and it works in that manner:

Main flow receives a string input and a maximum number for the hash output, it then takes the string input, plugs it in the SHA-1 hashing function.

SHA-1 hashing returns a Buffer, it takes that Buffer, and applies the hash-indexing on it, as can be seen in the following code excerpt:

return toNumber(crypto.createHash('sha1').update(input).digest()) % max

Also, it uses a modulu to make sure the hash index returned doesn't exceed the maximum possible hash.

like image 61
NadavL Avatar answered Nov 10 '22 00:11

NadavL