size and endian options to .toBuffer broken #1

Closed
paulhammond opened this Issue Feb 21, 2011 · 4 comments

Projects

None yet

2 participants

@paulhammond

The endian and size options for toBuffer don't appear to work:

var bigint = require('bigint');
b = bigint(43135012110)

console.log(b.toString(16))
console.log(b.toBuffer({ endian : 'big'    }))
console.log(b.toBuffer({ endian : 'little' }))
console.log(b.toBuffer({ endian : 'big'   , size:8 }))
console.log(b.toBuffer({ endian : 'little', size:8 }))

I get the following output from 2aad5f5:

a0b0c0d0e
<Buffer 0a 0b 0c 0d 0e>
<Buffer 0a 0b 0c 0d 0e>
<Buffer 0a>
<Buffer 00>

The last three buffers aren't what I expected.

@substack
Owner

How about now (bigint@0.0.7):

> var bigint = require('bigint');
> var b = bigint(43135012110);

> b.toString(16)
'a0b0c0d0e'

> b.toBuffer()
<Buffer 0a 0b 0c 0d 0e>

> b.toBuffer({ endian : 'big', size : 4 })
<Buffer 0a 0b 0c 0d 0e 00 00 00>

> b.toBuffer({ endian : 'little', size : 4 })
<Buffer 0d 0c 0b 0a 00 00 00 0e>

> b.toBuffer({ endian : 'big', size : 8 })
<Buffer 0a 0b 0c 0d 0e 00 00 00>

> b.toBuffer({ endian : 'little', size : 8 })
<Buffer 00 00 00 0e 0d 0c 0b 0a>

Note that when size = 1 (the default) there is no difference between endiannesses:

> b.toBuffer({ endian : 'little' })
<Buffer 0a 0b 0c 0d 0e>
> b.toBuffer({ endian : 'big' })
<Buffer 0a 0b 0c 0d 0e>

since endianness only makes sense in a multi-byte context.

@paulhammond

Thanks for the quick response, and sorry for the mistake when size = 1.

Either I'm misunderstanding the API, or the zero padding bytes are in the wrong place.

Here's some Ruby:

>> i = 0x123456
=> 1193046

# N is 32-bit unsigned integer, big endian byte order
>> [i].pack('N').bytes.map { |c| c.to_s(16) }
=> ["0", "12", "34", "56"]

# V is 32-bit unsigned integer, big endian byte order
>> [i].pack('V').bytes.map { |c| c.to_s(16) }
=> ["56", "34", "12", "0"]

Here's some javascript that I think should give similar results:

> b = bigint([0x123456])
<BigInt 1193046>

> b.toBuffer({ endian : 'big', size:4 })
<Buffer 12 34 56 00>

> b.toBuffer({ endian : 'little', size:4 })
<Buffer 00 56 34 12>

I expected this would give <Buffer 00 12 34 56> and <Buffer 56 34 12 00>. Am I missing something?

@substack
Owner

It seems there was an issue with zero-padding out the hex strings used for conversion properly. Now (v0.0.8) it agrees with ruby, at least in this particular instance.

> var bigint = require('bigint')
> var b = bigint(0x123456)
> b.toBuffer({ endian : 'big', size:4 })
<Buffer 00 12 34 56>
> b.toBuffer({ endian : 'little', size:4 })
<Buffer 56 34 12 00>

More failing cases are welcome!

@paulhammond

You seem to have covered it all. Thank you for creating node-bigint and for being responsive to bug reports!

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment