Node.js Secure Random Float from Crypto Buffer - javascript

Not for any practical purpose, of course, but I tried to generate a secure random floating point number using the Node's crypto module. Essentially, the following:
var crypto = require('crypto');
var buf = crypto.randomBytes(4);
var float = buf.readFloatBE();
This doesn't work, as far as the following test can tell, in an average of 0.40% of cases. Instead of getting a float, I get NaN.
var colors = require('colors');
var crypto = require('crypto');
var buf = new Buffer(4);
var fails = 0, tries = 100000;
var failures = [];
for (var i = 0; i < tries; i++) {
var num = crypto.randomBytes(4).readFloatBE(0);
try {
buf.writeFloatBE(num, 0);
} catch (e) {
fails++;
failures.push(buf.readUInt32BE(0).toString(2));
}
}
var percent = 100 * fails / tries;
if (fails)
percent = (percent.toFixed(2) + "%").red;
else
percent = '0.00%'.blue.bold;
console.log('Test ' + 'complete'.green.bold + ', ' + percent + ": " + fails + " / " + tries);
fails && console.log('Failed'.red + ' values:', failures.join(', '));
I'm guessing this is due to the IEEE single precision floating point number specification, but I'm not familiar with exactly how the float is stored as binary.
Why does this happen, exactly, and apart from simply generating floats until I get a valid number, how can I circumvent this?
EDIT: when looking at the filtered binary data, it appears they all follow the same pattern: the first 8 bits are all set. Everything else is random.

As is apparent from the current version of node, the buffer library's source specifies, on line 906, that the noAssert also checks to see if the Number provided is not NaN, so simply specifying noAssert allows writing of Infinity, NaN, and -Infinity to the buffer.

Related

SIP2 Checksum Calculation in Javascript

I'm working on a REST interface to a library system that uses the SIP2 protocol (https://en.wikipedia.org/wiki/Standard_Interchange_Protocol) and was able to get things working on a system that doesn't require error correction without a problem. However, my code is now talking to another system that requires checksums, described as so in the specification:
"To calculate the checksum add each character as an unsigned binary number, take the lower 16 bits of the total and perform a 2's complement. The checksum field is the result represented by four hex digits."
I've taken a few runs at this but not matter what I do I can't get a checksum back that matches my example message. I'm probably making this harder than it should be (seems like it would be easier in a lower-level language with proper binary types, etc.). Here's my latest attempt:
var checksum = 0;
var message = "63AOAA21221021780249|AD9999|AY0AZ";
// add each character as an unsigned binary number
for(var i=0;i<message.length;i++){
checksum += message[i].charCodeAt();
}
console.log("character sum: " + checksum);
// take the lower 16 bits of the total
checksum = checksum.toString(2);
console.log("character sum binary representation: " + checksum);
while(checksum.length < 16){
checksum = "0" + checksum;
}
checksum = checksum.substr(0,16);
console.log("lower 16 bits of character total: " + checksum);
// convert to dec
checksum = parseInt(checksum,2);
console.log("checksum dec: " + checksum);
// perform 2's complement
checksum = (checksum & 0xFFFF) * -1;
console.log("2s complement: " + checksum.toString(2));
// convert to 4 hex digits
checksum = dec2hex(checksum);
console.log("checksum hex: " + checksum);
function dec2hex(i) {
return (i+0x10000).toString(16).substr(-4).toUpperCase();
}
The expected checksum for the string above is "F39A".
I found a way to get there, it's probably not the most elegant approach, and certainly not high-performance, but it works reliably.
Here's the code should some other unfortunate soul find themselves looking to answer this question. I'm plan to bundle this up with some other SIP2-related bits in a library, but for now here's a function that will generate the checksum.
function sip2_checksum(message){
var checksum_int = 0;
var checksum_binary_string = "";
var checksum_binary_string_inverted = "";
var checksum_binary_string_inverted_plus1 = "";
var checksum_hex_string = "";
// add each character as an unsigned binary number
for(var i=0;i<message.length;i++){
checksum_int += message[i].charCodeAt();
}
// convert integer to binary representation stored in a string
while(checksum_int > 0){
checksum_binary_string = (checksum_int % 2).toString() + checksum_binary_string;
checksum_int = Math.floor(checksum_int / 2);
}
// pad binary string to 16 bytes
while(checksum_binary_string.length < 16){
checksum_binary_string = "0" + checksum_binary_string;
}
// invert the binary string
for(var i=0;i<checksum_binary_string.length;i++){
var inverted_value = "X"; // something weird to make mistakes jump out
if(checksum_binary_string[i] == "1"){
inverted_value = "0";
} else {
inverted_value = "1";
}
checksum_binary_string_inverted += inverted_value;
}
// add 1 to the binary string
var carry_bit = true;
for(var i=checksum_binary_string_inverted.length - 1;i>=0;i--){
if(carry_bit){
if(checksum_binary_string_inverted[i] === "0"){
checksum_binary_string_inverted_plus1 = "1" + checksum_binary_string_inverted_plus1;
carry_bit = false;
} else {
checksum_binary_string_inverted_plus1 = "0" + checksum_binary_string_inverted_plus1;
carry_bit = true;
}
} else {
checksum_binary_string_inverted_plus1 = checksum_binary_string_inverted[i] + checksum_binary_string_inverted_plus1;
}
}
// convert binary string to hex string and uppercase it because that's what the gateway likes
checksum_hex_string = parseInt(checksum_binary_string_inverted_plus1,2).toString(16).toUpperCase();
return checksum_hex_string;
}

how to convert big decimal value to decimal in javascript

var zx =1800;
I have some value in big decimal value i need to convert it as decimal in javascript.
I have tried using zx.doubleValue() method but i m getting error as "Uncaught ReferenceError: Double is not defined" In browser console.
var bigdecimal = require("bigdecimal");
var i = new bigdecimal.BigInteger("1234567890abcdefghijklmn", 24);
console.log("i is " + i);
// Output: i is 60509751690538858612029415201127
var d = new bigdecimal.BigDecimal(i);
var x = new bigdecimal.BigDecimal("123456.123456789012345678901234567890");
console.log("d * x = " + d.multiply(x));
// Output: d * x = 7470299375046812977089832214047022056.555930270554343863089286012030
var two = new bigdecimal.BigDecimal('2');
console.log("Average = " + d.add(x).divide(two));
// Output: Average = 30254875845269429306014707662291.561728394506172839450617283945
var down = bigdecimal.RoundingMode.DOWN();
console.log("d / x (25 decimal places) = " + d.divide(x, 25, DOWN));
// Output: d / x (25 decimal places) = 490131635404200348624039911.8662623025579331926181155
As I understood you receiving big decimal from backend. The problem with JavaScript is that native Number type is limited in precision, thus your big decimal will be truncated.
You can use one of libraries, for example, big number:
https://www.npmjs.com/package/big-numbers
This will allow you to convert received from backend numbers to big number:
const bigNumberValue = numbers.of([received from backend value]);
After it is done, you can perform any required operation: add, multiply, etc. Check JavaScript tutorial here:
http://bignumbers.tech/tutorials/java-script

How can I find the length of a number?

I'm looking to get the length of a number in JavaScript or jQuery?
I've tried value.length without any success, do I need to convert this to a string first?
var x = 1234567;
x.toString().length;
This process will also work forFloat Number and for Exponential number also.
Ok, so many answers, but this is a pure math one, just for the fun or for remembering that Math is Important:
var len = Math.ceil(Math.log(num + 1) / Math.LN10);
This actually gives the "length" of the number even if it's in exponential form. num is supposed to be a non negative integer here: if it's negative, take its absolute value and adjust the sign afterwards.
Update for ES2015
Now that Math.log10 is a thing, you can simply write
const len = Math.ceil(Math.log10(num + 1));
Could also use a template string:
const num = 123456
`${num}`.length // 6
You have to make the number to string in order to take length
var num = 123;
alert((num + "").length);
or
alert(num.toString().length);
I've been using this functionality in node.js, this is my fastest implementation so far:
var nLength = function(n) {
return (Math.log(Math.abs(n)+1) * 0.43429448190325176 | 0) + 1; 
}
It should handle positive and negative integers (also in exponential form) and should return the length of integer part in floats.
The following reference should provide some insight into the method:
Weisstein, Eric W. "Number Length." From MathWorld--A Wolfram Web Resource.
I believe that some bitwise operation can replace the Math.abs, but jsperf shows that Math.abs works just fine in the majority of js engines.
Update: As noted in the comments, this solution has some issues :(
Update2 (workaround) : I believe that at some point precision issues kick in and the Math.log(...)*0.434... just behaves unexpectedly. However, if Internet Explorer or Mobile devices are not your cup of tea, you can replace this operation with the Math.log10 function. In Node.js I wrote a quick basic test with the function nLength = (n) => 1 + Math.log10(Math.abs(n) + 1) | 0; and with Math.log10 it worked as expected. Please note that Math.log10 is not universally supported.
There are three way to do it.
var num = 123;
alert(num.toString().length);
better performance one (best performance in ie11)
var num = 123;
alert((num + '').length);
Math (best performance in Chrome, firefox but slowest in ie11)
var num = 123
alert(Math.floor( Math.log(num) / Math.LN10 ) + 1)
there is a jspref here
http://jsperf.com/fastest-way-to-get-the-first-in-a-number/2
You should go for the simplest one (stringLength), readability always beats speed. But if you care about speed here are some below.
Three different methods all with varying speed.
// 34ms
let weissteinLength = function(n) {
return (Math.log(Math.abs(n)+1) * 0.43429448190325176 | 0) + 1;
}
// 350ms
let stringLength = function(n) {
return n.toString().length;
}
// 58ms
let mathLength = function(n) {
return Math.ceil(Math.log(n + 1) / Math.LN10);
}
// Simple tests below if you care about performance.
let iterations = 1000000;
let maxSize = 10000;
// ------ Weisstein length.
console.log("Starting weissteinLength length.");
let startTime = Date.now();
for (let index = 0; index < iterations; index++) {
weissteinLength(Math.random() * maxSize);
}
console.log("Ended weissteinLength length. Took : " + (Date.now() - startTime ) + "ms");
// ------- String length slowest.
console.log("Starting string length.");
startTime = Date.now();
for (let index = 0; index < iterations; index++) {
stringLength(Math.random() * maxSize);
}
console.log("Ended string length. Took : " + (Date.now() - startTime ) + "ms");
// ------- Math length.
console.log("Starting math length.");
startTime = Date.now();
for (let index = 0; index < iterations; index++) {
mathLength(Math.random() * maxSize);
}
First convert it to a string:
var mynumber = 123;
alert((""+mynumber).length);
Adding an empty string to it will implicitly cause mynumber to turn into a string.
Well without converting the integer to a string you could make a funky loop:
var number = 20000;
var length = 0;
for(i = number; i > 1; ++i){
++length;
i = Math.floor(i/10);
}
alert(length);​
Demo: http://jsfiddle.net/maniator/G8tQE/
I got asked a similar question in a test.
Find a number's length without converting to string
const numbers = [1, 10, 100, 12, 123, -1, -10, -100, -12, -123, 0, -0]
const numberLength = number => {
let length = 0
let n = Math.abs(number)
do {
n /= 10
length++
} while (n >= 1)
return length
}
console.log(numbers.map(numberLength)) // [ 1, 2, 3, 2, 3, 1, 2, 3, 2, 3, 1, 1 ]
Negative numbers were added to complicate it a little more, hence the Math.abs().
I'm perplex about converting into a string the given number because such an algorithm won't be robust and will be prone to errors: it will show all its limitations especially in case it has to evaluate very long numbers. In fact before converting the long number into a string it will "collapse" into its exponential notation equivalent (example: 1.2345e4). This notation will be converted into a string and this resulting string will be evaluated for returning its length. All of this will give a wrong result. So I suggest not to use that approach.
Have a look at the following code and run the code snippet to compare the different behaviors:
let num = 116234567891011121415113441236542134465236441625344625344625623456723423523429798771121411511034412365421344652364416253446253446254461253446221314623879235441623683749283441136232514654296853446323214617456789101112141511344122354416236837492834411362325146542968534463232146172368374928344113623251465429685;
let lenFromMath;
let lenFromString;
// The suggested way:
lenFromMath = Math.ceil(Math.log10(num + 1)); // this works in fact returns 309
// The discouraged way:
lenFromString = String(num).split("").length; // this doesn't work in fact returns 23
/*It is also possible to modify the prototype of the primitive "Number" (but some programmer might suggest this is not a good practice). But this is will also work:*/
Number.prototype.lenght = () => {return Math.ceil(Math.log10(num + 1));}
lenFromPrototype = num.lenght();
console.log({lenFromMath, lenFromPrototype, lenFromString});
A way for integers or for length of the integer part without banal converting to string:
var num = 9999999999; // your number
if (num < 0) num = -num; // this string for negative numbers
var length = 1;
while (num >= 10) {
num /= 10;
length++;
}
alert(length);
I would like to correct the #Neal answer which was pretty good for integers, but the number 1 would return a length of 0 in the previous case.
function Longueur(numberlen)
{
var length = 0, i; //define `i` with `var` as not to clutter the global scope
numberlen = parseInt(numberlen);
for(i = numberlen; i >= 1; i)
{
++length;
i = Math.floor(i/10);
}
return length;
}
To get the number of relevant digits (if the leading decimal part is 0 then the whole part has a length of 0) of any number separated by whole part and decimal part I use:
function getNumberLength(x) {
let numberText = x.toString();
let exp = 0;
if (numberText.includes('e')) {
const [coefficient, base] = numberText.split('e');
exp = parseInt(base, 10);
numberText = coefficient;
}
const [whole, decimal] = numberText.split('.');
const wholeLength = whole === '0' ? 0 : whole.length;
const decimalLength = decimal ? decimal.length : 0;
return {
whole: wholeLength > -exp ? wholeLength + exp : 0,
decimal: decimalLength > exp ? decimalLength - exp : 0,
};
}
var x = 1234567;
String(x).length;
It is shorter than with .toString() (which in the accepted answer).
Try this:
$("#element").text().length;
Example of it in use
Yes you need to convert to string in order to find the length.For example
var x=100;// type of x is number
var x=100+"";// now the type of x is string
document.write(x.length);//which would output 3.

Seeded random number

Ive been wondering for some time. Is there a good (And fast) way to make an number random while its seeded?
is there a good algorithm to convert one number into a seemingly random number.
A little illustration:
specialrand(1) = 8
specialrand(2) = 5
specialrand(3) = 2
specialrand(4) = 5
specialrand(5) = 1
specialrand(1) = 8
specialrand(4) = 5
specialrand(1) = 8
It would be very nice if the output could also be huge numbers.
As a note: I don't want to fill a array and randomize the numbers because I want to be able to feed it huge difference of numbers because I want the same output whenever I restart the program
You're not looking for a seeded random number. Instead what I think you're looking for is a hashing function. If you put in the same input and get the same output, that's not random.
If you're looking to generate a sequence of random numbers for a run, but have the same sequence generate from run to run, you can use a random number generator that generates the same sequence given the same seed value.
Thats how most basic pRNG's work. There are more cryptographically secure RNG's out there, but your standard Math.rand() should work to accomplish your needs.
Maybe pseudorandom number generators are what you are looking for.
For example the XORshift.
uint32_t xor128(void) {
static uint32_t x = 123456789;
static uint32_t y = 362436069;
static uint32_t z = 521288629;
static uint32_t w = 88675123;
uint32_t t;
t = x ^ (x << 11);
x = y; y = z; z = w;
return w = w ^ (w >> 19) ^ (t ^ (t >> 8));
}
You could create something like this:
take a seed
specialrand(5) is a function which takes the fifth random number from this seed
or specialrand(5) is a function which gets the first random number from the seed+5
Maybe this is enough for your purpose.
Try setting a key or set of keys then writing a function with an equation to return a new number based on that key:
a very basic example would be:
function specialrand(value) {
key = array (1,2,4,6,8);
for (k in key) {
if (k%2 === 0) {
value -= key[k] * value;
} else {
value += key[k] / value;
}
}
return value;
}
however you could create a highly complex equation to generate your 'random' number and ensure you return the same number each time.
You can use Date functionality
Math.valueOfSeed = function(n)
{
return Number(new Date(n%9999, n%12, n%30, n%24, n%60, n%60, n%1000));
};
alert(Math.valueOfSeed(1) + " = " + Math.valueOfSeed(1));
alert(Math.valueOfSeed(2) + " = " + Math.valueOfSeed(2));
alert(Math.valueOfSeed(15) + " = " + Math.valueOfSeed(15));
alert(Math.valueOfSeed(5555) + " = " + Math.valueOfSeed(5555));
alert(Math.valueOfSeed(21212121) + " = " + Math.valueOfSeed(21212121));
alert(Math.valueOfSeed(6554654654) + " = " + Math.valueOfSeed(6554654654));​
test is here

JavaScript summing large integers

In JavaScript I would like to create the binary hash of a large boolean array (54 elements) with the following method:
function bhash(arr) {
for (var i = 0, L = arr.length, sum = 0; i < L; sum += Math.pow(2,i)*arr[i++]);
return sum;
}
In short: it creates the smallest integer to store an array of booleans in. Now my problem is that javascript apparently uses floats as default. The maximum number I have to create is 2^54-1 but once javascript reaches 2^53 it starts doing weird things:
9007199254740992+1 = 9007199254740994
Is there any way of using integers instead of floats in javascript? Or large integer summations?
JavaScript uses floating point internally.
What is JavaScript's highest integer value that a number can go to without losing precision?
In other words you can't use more than 53 bits. In some implementations you may be limited to 31.
Try storing the bits in more than one variable, use a string, or get a bignum library, or if you only need to deal with integers, a biginteger library.
BigInt is being added as a native feature of JavaScript.
typeof 123;
// → 'number'
typeof 123n;
// → 'bigint'
Example:
const max = BigInt(Number.MAX_SAFE_INTEGER);
const two = 2n;
const result = max + two;
console.log(result);
// → '9007199254740993'
javascript now has experimental support for BigInt.
At the time of writing only chrome supports this.
caniuse has no entry yet.
BigInt can be either used with a constructor, e.g. BigInt(20) or by appending n, e.g. 20n
Example:
const max = Number.MAX_SAFE_INTEGER;
console.log('javascript Number limit reached', max + 1 === max + 2) // true;
console.log('javascript BigInt limit reached', BigInt(max) + 1n === BigInt(max) + 2n); // false
No. Javascript only has one numeric type. You've to code yourself or use a large integer library (and you cannot even overload arithmetic operators).
Update
This was true in 2010... now (2019) a BigInt library is being standardized and will most probably soon arrive natively in Javascript and it will be the second numeric type present (there are typed arrays, but - at least formally - values extracted from them are still double-precision floating point numbers).
Another implementation of large integer arithmetic (also using BigInt.js) is available at www.javascripter.net/math/calculators/100digitbigintcalculator.htm. Supports the operations + - * / as well as remainder, GCD, LCM, factorial, primality test, next prime, previous prime.
So while attempting one of the leetcode problem I have written a function which takes two numbers in form of string and returns the sum of those numbers in form of string.
(This doesn't work with negative numbers though we can modify this function to cover that)
var addTwoStr = function (s1, s2) {
s1 = s1.split("").reverse().join("")
s2 = s2.split("").reverse().join("")
var carry = 0, rS = '', x = null
if (s1.length > s2.length) {
for (let i = 0; i < s1.length; i++) {
let s = s1[i]
if (i < s2.length) {
x = Number(s) + Number(s2[i]) + carry
rS += String((x % 10))
carry = parseInt(x/10)
} else {
if (carry) {
x = Number(s) + carry
rS += String((x % 10))
carry = parseInt(x/10)
} else {
rS += s
}
}
}
} else {
for (let i = 0; i < s2.length; i++) {
let s = s2[i]
if (i < s1.length) {
x = Number(s) + Number(s1[i]) + carry
rS += String((x % 10))
carry = parseInt(x/10)
} else {
if (carry) {
x = Number(s) + carry
rS += String((x % 10))
carry = parseInt(x/10)
} else {
rS += s
}
}
}
}
if (carry) {
rS += String(carry)
}
return rS.split("").reverse().join("")
}
Example: addTwoStr('120354566', '321442535')
Output: "441797101"
There are various BigInteger Javascript libraries that you can find through googling. e.g. http://www.leemon.com/crypto/BigInt.html
Here's (yet another) wrapper around Leemon Baird's BigInt.js
It is used in this online demo of a big integer calculator in JavaScript which implements the usual four operations + - * /, the modulus (%), and four builtin functions : the square root (sqrt), the power (pow), the recursive factorial (fact) and a memoizing Fibonacci (fibo).
You're probably running into a byte length limit on your system. I'd take the array of booleans, convert it to an array of binary digits ([true, false, true] => [1,0,1]), then join this array into a string "101", then use parseInt('101',2), and you'll have your answer.
/** --if you want to show a big int as your wish use install and require this module
* By using 'big-integer' module is easier to use and handling the big int numbers than regular javascript
* https://www.npmjs.com/package/big-integer
*/
let bigInt = require('big-integer');
//variable: get_bigInt
let get_bigInt = bigInt("999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999");
let arr = [1, 100000, 21, 30, 4, BigInt(999999999999), get_bigInt.value];
console.log(arr[6]); // Output: 999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999n
//Calculation
console.log(arr[6] + 1n); // +1
console.log(arr[6] + 100n); // +100
console.log(arr[6] - 1n); // -1
console.log(arr[6] - 10245n); // -1000n
console.log((arr[6] * 10000n) + 145n - 435n);

Categories

Resources