2017-03-15 24 views
5

Tôi đang làm việc trên một hệ thống tạo ra khoảng 2 tỷ UUID duy nhất mỗi ngày. UUID được tạo bằng JavaScript \ Flash (AS3) trên máy khách.Tạo các UUID thực sự độc đáo trong JavaScript và AS3 - PRNG và các thuật toán cơ bản

Gần đây chúng tôi nhận thấy rằng các UUID của chúng tôi không có nơi gần độc đáo. Chúng tôi có khoảng 20% ​​(!) Bản sao hàng ngày, hầu hết trong số đó (liên quan đến lưu lượng truy cập) đến từ chrome.

Tôi đã thực hiện some readingand learnedthat the pseudo-random triển khai thuật toán thế hệ (PRNG) trên hầu hết các trình duyệt và đặc biệt là chrome, là thiếu sót. Chromium và Node.js sử dụng công cụ V8Script V8, thực hiện một thuật toán gọi là MWC1616. Theo lý thuyết, UUID được tạo ra bằng cách sử dụng PRNG tốt phải có 2132 probability cho va chạm, nhưng với MWC1616, trong một số trường hợp rất thực tế, xác suất này là khoảng 1: 30000.

Để giải quyết vấn đề, tôi coi các tùy chọn sau:

  1. Tạo ID trên máy chủ (sử dụng Go)
  2. Tạo một ID mạnh trên máy khách, bằng cách băm một số thông tin như IP, UA , dấu thời gian, v.v. với UUID.
  3. Thay thế Math.random() bằng trình tạo ngẫu nhiên tốt hơn.

Vì tôi muốn giữ chúng trên máy khách và tôi không muốn tái phát minh ra bánh xe và sửa đổi logic tạo UUID, tôi muốn gắn bó với tùy chọn 3.

Tin tốt lành là trên các trình duyệt mới hơn, có api getRandomValues. Thật không may, tôi cần hỗ trợ các trình duyệt cũ hơn.

Vì vậy, câu hỏi của tôi là:

  1. một tốt và đáng tin cậy polyfill JavaScript cho

crypto.getRandomValues ​​()

(mà không sử dụng Math là gì .random nội bộ)?

  1. AS3 Math.random() có sử dụng Math.random() của trình duyệt không? Liệu nó có thực hiện cùng một thuật toán không?

  2. Flash.crypto.generateRandomBytes() có sử dụng Math.random() không? Nó có sử dụng crypto.getRandomValues ​​() không? Nếu không, thuật toán nào nó thực hiện và nó sẽ là một giải pháp tốt cho cùng một vấn đề trong AS3? Nếu không, bạn nên giới thiệu thư viện mã hóa AS3 nào?

P.S. Tôi đánh giá cao các bài viết tôi đã đề cập -1--2--3-. Tôi đã nhận thức được các vấn đề với Math.random() trong nhiều năm, nhưng bài viết này thực sự làm cho nó rõ ràng với tôi cho tốt.

+2

Math.random() của AS3 là trình duyệt độc lập nhưng vẫn giả ngẫu nhiên. AS3 có một phương thức UIDUtil.createUID() nhưng như đã nêu trong các tài liệu "UID này sẽ không thực sự độc đáo trên toàn cầu, nhưng tốt nhất chúng ta có thể làm mà không cần hỗ trợ trình phát để tạo UID". Tôi đang sử dụng lớp này cho thế hệ GUID và nó hoạt động khá tốt cho đến nay (với vài nghìn ID được tạo mỗi ngày): http://snipplr.com/view/45247/as3-globally-unique-identifier-guid/ – Philarmon

+0

@Philarmon - Tôi nghi ngờ điều này sẽ không đủ tốt cho tải của chúng tôi - Việc triển khai UIDUtil rất giống với việc triển khai hiện tại tôi đang sử dụng Math.random. Bạn có kinh nghiệm với crypto.generateRandomBytes không? – Lizozom

+1

Hãy thử 'forge.random.getBytesSync (numbytes);' Có vẻ là [random.js] của forges (https://github.com/digitalbazaar/forge/blob/master/lib/random.js) sử dụng trình tạo ngẫu nhiên của riêng nó khi ' window.crypto.getRandomValues ​​() 'không có sẵn và có thể bị buộc sử dụng' forge.options.usePureJavaScript = true; ' – pedrofb

Trả lời

2

Sau khi dành hơn một tuần nghiên cứu điều này - kết luận của tôi là: KHÔNG BAO GIỜ TẠO UUID trên máy khách. Chỉ cần không.Đặc biệt là nếu bạn có ý định mở rộng quy mô.

Trong nhiều năm, tôi biết rằng việc thực thi Math.random của trình duyệt rất kém, nhưng tôi không hiểu nó tệ như thế nào, cho đến khi chúng tôi đạt đến hàng tỷ sự kiện mỗi ngày.

Tôi quyết định đi với giải pháp kỹ thuật đơn giản nhất và di chuyển UUID thế hệ sang máy chủ. Tỷ lệ ID trùng lặp khi giảm từ ~ 25% một ngày thành ~ 0,0008%.

P.S. Máy chủ của chúng tôi được triển khai trong Go. Node.js sử dụng công cụ JavaScript V8 và có thể có cùng vấn đề. Mặc dù nó có vẻ như nếu bạn đang sử dụng Node.js mới nhất, bạn nên ổn.

+1

http://dilbert.com/strip/2001-10-25 :) –

+0

Tôi không nghĩ rằng nó cần thiết để đi xa như vậy để nói, "không bao giờ tạo ra UUID trên máy khách". Có rất nhiều lợi ích khi tạo ID chính tắc cùng lúc bạn tạo một thực thể dữ liệu, trong thế giới ngày càng tập trung vào điện thoại di động của chúng tôi, xảy ra thường xuyên hơn trên máy khách. Và cũng lưu ý rằng bạn chạy vào tất cả các vấn đề tương tự tạo ID trên máy chủ ngay sau khi bạn phải mở rộng vượt quá một máy chủ duy nhất. Các takeaway thực sự ở đây là không bao giờ giả định ID của bạn được đảm bảo là duy nhất. Đặt kiểm tra cho điều này tại chỗ và thất bại một cách duyên dáng khi một vụ va chạm xảy ra. – broofa

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