Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

calculateParameters seems to be broken on node #4

Open
adrian-gierakowski opened this issue Jan 3, 2018 · 2 comments
Open

calculateParameters seems to be broken on node #4

adrian-gierakowski opened this issue Jan 3, 2018 · 2 comments

Comments

@adrian-gierakowski
Copy link

calculateParameters(Math.pow( 2, 31 )) => { bitsNeeded: 32, bytesNeeded: 4, mask: -1 }
calculateParameters(Math.pow( 2, 32 )) => { bitsNeeded: 1, bytesNeeded: 1, mask: 3 }
calculateParameters(Number.MAX_SAFE_INTEGER) => { bitsNeeded: 32, bytesNeeded: 4, mask: -1 }

tested with node 6 and 7
see: https://repl.it/repls/SuperUpbeatNandoo

@almic
Copy link

almic commented Feb 16, 2018

This looks like a limitation of how Javascript implements numbers, and the bitwise operators in javascript, which convert the signed 64 bit floating point numbers to 32 bit integers before operating on them. Why they made it like that, I have no clue. Compatibility? Maybe just oversight?

From https://www.w3schools.com/js/js_bitwise.asp on 2/15/2018

JavaScript Uses 32 bits Bitwise Operands

JavaScript stores numbers as 64 bits floating point numbers, but all bitwise operations are performed on 32 bits binary numbers.

Before a bitwise operation is performed, JavaScript converts numbers to 32 bits signed integers.
After the bitwise operation is performed, the result is converted back to 64 bits JavaScript numbers.

The examples above uses 4 bits unsigned binary numbers. Because of this ~ 5 returns 10.
Since JavaScript uses 32 bits signed integers, it will not return 10. It will return -6.

00000000000000000000000000000101 (5)
11111111111111111111111111111010 (~5 = -6)

A signed integer uses the leftmost bit as the minus sign.

This seems to be exactly what's happening here. For now, just don't use ranges any bigger than 2^32 - 1, or 4,294,97,295. As long as the range is smaller than 2^32, the numbers won't overflow. Use numbers as big as MAX_SAFE_INTEGER, but the range can't be bigger than 2^32.

Then again, if you are trying to generate numbers that big, then going through the effort of making it slightly more secure with all this fluff is trumped by sheer size of possible options.

(Not exactly a professional, but I'm sure there's a number library for bitwise operations on large numbers. Implementing it yourself and making a pull request should take a few minutes if you really need ranges that big.)

@PROger4ever
Copy link

Can we fix it anyway? I don't know, maybe replace bitwise operators with dividing/subtracting or something like that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants