2016-01-03 15 views
5

Làm thế nào để bạn tạo ra cryptographically secure nổi trong Javascript?Float an toàn mã hóa

Đây phải là một trình cắm cho Math.random, có phạm vi (0, 1), nhưng bảo mật về mặt mã hóa. Ví dụ về cách sử dụng

cryptoFloat.random(); 
0.8083966837153522 

Secure random numbers in javascript? cho biết cách tạo Uint32Array bảo mật mã hóa. Có lẽ điều này có thể được chuyển đổi thành một phao bằng cách nào đó?

+1

Bạn chỉ cần hỗ trợ các trình duyệt hỗ trợ 'window.crypto'? –

+1

@ T.J.Crowder: Trên thực tế, đối với trường hợp sử dụng của tôi, Firefox sẽ đủ. Tổng quát hơn, các merrier. –

+1

Chỉ cần gắn cờ nó ở mức cao: float của JavaScript là số IEEE-754 64 bit (tốt, bạn có thể nhận được 32 bit nếu muốn), có nghĩa là chúng chỉ có 53 chữ số nhị phân đáng kể (hiệu quả) . Điều đó không đủ cho hầu hết mọi mục đích mã hóa. –

Trả lời

4

Vì mã sau đây khá đơn giản và functionally equivalent to the division method, đây là alternate method of altering the bits. (Mã này được sao chép và sửa đổi từ @ T.J. Câu trả lời rất hữu ích của Crowder).

// A buffer with just the right size to convert to Float64 
 
let buffer = new ArrayBuffer(8); 
 

 
// View it as an Int8Array and fill it with 8 random ints 
 
let ints = new Int8Array(buffer); 
 
window.crypto.getRandomValues(ints); 
 

 
// Set the sign (ints[7][7]) to 0 and the 
 
// exponent (ints[7][6]-[6][5]) to just the right size 
 
// (all ones except for the highest bit) 
 
ints[7] = 63; 
 
ints[6] |= 0xf0; 
 

 
// Now view it as a Float64Array, and read the one float from it 
 
let float = new DataView(buffer).getFloat64(0, true) - 1; 
 
document.body.innerHTML = "The number is " + float;

Giải thích:

The format of a IEEE754 double là 1 dấu hiệu bit (ints[7][7]), 11 bit số mũ (ints[7][6]-ints[6][5]), và phần còn lại như mantissa (nắm giữ các giá trị). Công thức để tính toán là

(-1)<sup>sign</sup> (1 + Σ<sub>i=1</sub><sup>52</sup> b<sub>52-i</sub> 2<sup>i</sup>) * 2<sup>e-1023</sup>

Để thiết lập các yếu tố đến 1, số mũ cần phải được 1023. Nó có 11 bit, do đó các bit cao nhất để cung cấp cho 2048. Điều này cần phải được thiết lập để 0, các bit khác để 1.

+0

Tuyệt. Bạn đã xác định rằng điều bất thường không phải là một vấn đề, hay ...? –

+0

@ T.J.Crowder: Điều này sử dụng số bit tối đa. Hãy xem xét rằng mỗi bit của mantissa "chia khoảng thời gian" bởi 2: Đầu tiên hoặc là thêm 1/2 hoặc 0, thứ hai thêm 1/4 hoặc 0, 1/8 hoặc 0, ... Có vẻ như vấn đề của các số ngẫu nhiên chỉ xảy ra nếu bạn bao gồm số mũ. (Sau đó, các con số rõ ràng là logarithmically khoảng cách). Cảm ơn bạn. Có lẽ tôi sẽ không thực hiện nó nếu không có sự giúp đỡ của bạn. (đã không làm việc với JS FloatArrays vv trước) –

+1

Bạn đang chào đón, tôi rất vui vì đã giúp. Re subnormals, bây giờ tôi đã đọc nó một lần nữa một vài giờ sau đó, tôi không nghĩ rằng đó là một vấn đề; phương thức của bạn nên phân phối đồng đều các giá trị trên phạm vi số mà 'Số' có thể biểu diễn chính xác. Subnormals mở rộng phạm vi bằng cách thỏa hiệp độ chính xác. Tôi không nghĩ rằng bạn đang mất bất cứ điều gì từ một quan điểm ngẫu nhiên bằng cách để chúng ra. –

Các vấn đề liên quan