Kev*_*vin 1 javascript hash encoding
考虑以下btoa输出
btoa(99999999999999999999)
"MTAwMDAwMDAwMDAwMDAwMDAwMDAw"
btoa(99999999999999999998)
"MTAwMDAwMDAwMDAwMDAwMDAwMDAw"
btoa("99999999999999999998")
"OTk5OTk5OTk5OTk5OTk5OTk5OTg="
btoa("99999999999999999999")
"OTk5OTk5OTk5OTk5OTk5OTk5OTk="
Run Code Online (Sandbox Code Playgroud)
我们看到btoa无法编码20位数的唯一哈希,int但能够编码20位数string.为什么是这样?
我最初的猜测是,既然btoa是基础,64它只能编码低于基数的东西64,但为什么它能够编码20位string呢?
而且btoa似乎不能编码int少于9223372036854775807a2^63
btoa(9223372036854775302)
"OTIyMzM3MjAzNjg1NDc3NjAwMA=="
btoa(9223372036854775303)
"OTIyMzM3MjAzNjg1NDc3NjAwMA=="
Run Code Online (Sandbox Code Playgroud)
因为浮点不精确.请记住,JavaScript 在某些计算过程中暂时没有整数 ; 所有JavaScript编号都是IEEE-754双精度浮点数.99999999999999999999在IEEE-754数字中不是安全的整数值,事实上如果你这样做:
console.log(99999999999999999999);
Run Code Online (Sandbox Code Playgroud)
...你会看到的
100000000000000000000
最大安全整数(例如,不受浮点不精确影响的整数)是9007199254740991.
因为btoa接受一个字符串(当你传递一个数字,数字只是转换为字符串),只需在你的值周围加上引号:
btoa("99999999999999999999")
=> OTk5OTk5OTk5OTk5OTk5OTk5OTk=
Run Code Online (Sandbox Code Playgroud)
当然,如果值是数学计算的结果,则不能这样做.您将不得不更改计算如此大数字的任何内容,因为它们超出了数字类型的精确范围.