2016-03-23 13 views
1

Betrachten Sie die folgenden btoa AusgabeWarum funktioniert `btoa` in JavaScript für 20-stellige Zeichenfolge und nicht 20-stellige int?

btoa(99999999999999999999) 
"MTAwMDAwMDAwMDAwMDAwMDAwMDAw" 

btoa(99999999999999999998) 
"MTAwMDAwMDAwMDAwMDAwMDAwMDAw" 

btoa("99999999999999999998") 
"OTk5OTk5OTk5OTk5OTk5OTk5OTg=" 

btoa("99999999999999999999") 
"OTk5OTk5OTk5OTk5OTk5OTk5OTk=" 

Wir sehen, dass btoa nicht in der Lage ist, für 20-stellige int eindeutige Hash zu kodieren, konnte aber string 20 Ziffer kodieren. Warum ist das?

Meine ursprüngliche Vermutung ist, dass seit btoa Basis ist 64 es nur etwas kodieren kann, die weniger als Basis ist 64, aber warum es zum Codieren eine 20-stellige string stattdessen fähig ist?

Außerdem btoa scheint nicht in der Lage zu int kodieren weniger als 9223372036854775807, die eine Wegen Gleitkomma Unschärfen 2^63

btoa(9223372036854775302) 
"OTIyMzM3MjAzNjg1NDc3NjAwMA==" 

btoa(9223372036854775303) 
"OTIyMzM3MjAzNjg1NDc3NjAwMA==" 

Antwort

6

ist. Denken Sie daran, dass JavaScript Ganzzahlen außer vorübergehend während bestimmter Berechnungen nicht hat; Alle JavaScript-Nummern sind IEEE-754 Gleitkommazahl mit doppelter Genauigkeit. 99999999999999999999 ist kein sicherer Integer-Wert in IEEE-754-Nummern, und in der Tat, wenn Sie dies tun:

console.log(99999999999999999999); 

... Sie werden

 
100000000000000000000 

Die maximale sichere ganze Zahl (zB integer sehen das wird nicht von Gleitkomma-Ungenauigkeit beeinflusst) ist 9007199254740991.

Da btoa akzeptiert einen String (wenn Sie es eine Reihe passieren, nur die Zahl in String umgewandelt wird), nur Anführungszeichen um den Wert:

btoa("99999999999999999999") 
=> OTk5OTk5OTk5OTk5OTk5OTk5OTk= 

Natürlich, wenn der Wert der ist Ergebnis einer mathematischen Berechnung, können Sie das nicht tun. Sie müssen alles ändern, was so große Zahlen berechnet, da sie den genauen Bereich des Zahlentyps überschreiten.

+0

Danke, das macht Sinn, aber warum ist JavaScript in der Lage, 20-stellige 'string' zu codieren? Sicher 20-stellige 'string' nehmen mehr als 20stellige' int', da jede Ziffer in 'string' mehr als 10 Möglichkeiten hat – Kevin

+0

@Kevin:' btoa' arbeitet immer mit Strings. Wenn Sie etwas übergeben, das keine Zeichenkette ist, ruft es als erstes "toString" auf (in der Tat). Das hat nichts mit 'btoa' zu tun, es ist nur die Natur von JavaScript-Nummern: Diese Nummer wird nicht genau eingehalten, und wenn man damit etwas macht (wie' toString'), kommt es anders als das Literal '99999999999999999999' Du hast mit angefangen. –

+0

Ah ich sehe, so Base 64-Codierung ist es möglich, Zeichenfolge größer als 64 Bit zu codieren? Garantiert die Btoa in diesem Fall die Eindeutigkeit von Hash? – Kevin

Verwandte Themen