Điểm:0

bạn có thể tạo số ID một cách nhanh chóng, không có xung đột và không có ID tiết lộ thông tin không?

lá cờ ru

Có cách tiêu chuẩn nào để tạo số ID lần lượt sao cho:

  • Bạn có thể đảm bảo, hoặc gần như đảm bảo, rằng bạn tránh va chạm. (Theo "gần như đảm bảo", ý tôi là ví dụ: nếu bạn tạo các số có 24 chữ số hoàn toàn ngẫu nhiên và bạn "chỉ" tạo ra 1 triệu trong số đó, thì ngay cả với nghịch lý ngày sinh, tỷ lệ va chạm sẽ rất nhỏ.)
  • Bạn muốn số ID ngắn gọn, không khó sử dụng - cụ thể là bạn đừng muốn dựa vào độ dài của số ID (và chọn các giá trị ngẫu nhiên) để tránh xung đột, như được mô tả trong dấu đầu dòng trước đó. Bạn phải làm điều đó một số cách khác.
  • Bạn không muốn tránh xung đột mỗi khi tạo một giá trị mới bằng cách xem tất cả các giá trị có sẵn để xem giá trị đó đã được sử dụng chưa. Đây sẽ chỉ là tra cứu nhật ký (n) mỗi lần trong danh sách được sắp xếp, nhưng giả sử tôi muốn tránh điều này.
  • Bạn không muốn số ID tiết lộ bất kỳ thông tin nào về thời điểm tạo hoặc số lượng ID được tạo giữa số ID X và số ID Y. Không có điều kiện này, vấn đề là tầm thường; bạn chỉ có thể sử dụng thời gian của đồng hồ (cộng với một số giá trị ngẫu nhiên đủ lớn để tránh xung đột giữa các số được tạo trong cùng một giá trị thời gian của đồng hồ) hoặc bạn chỉ có thể sử dụng các số nguyên tuần tự (ngoại trừ bây giờ kẻ tấn công biết rằng nếu ai đó tạo giá trị ID 5000 trên Ngày 1 tháng 3 và giá trị ID 6000 vào ngày 1 tháng 4, có 1000 giá trị khác được tạo trong khoảng thời gian đó).

Tôi đã cố gắng tìm một câu trả lời tầm thường, nhưng không có câu trả lời nào tôi thử có vẻ hiệu quả. Bạn chỉ có thể lấy hàm băm SHA-256 của các số 1, 2, 3, v.v. (cộng với một số khóa bí mật), nhưng điều này có cùng vấn đề với việc chỉ chọn các số ngẫu nhiên từ không gian có sẵn -- nếu bạn đang dựa vào độ dài của hàm băm (ví dụ: SHA-256) để tránh xung đột, số ID thu được sẽ dài và khó sử dụng, đồng thời nếu bạn tạo hàm băm ngắn hơn, bạn sẽ tăng khả năng xảy ra xung đột.

Hoặc bạn có thể tạo ID mới bằng cách tăng mỗi lần một giá trị ngẫu nhiên trong khoảng từ 1 đến n, thay vì luôn tăng theo 1. Vấn đề là tùy thuộc vào những gì kẻ tấn công có thể làm, chúng có thể tìm ra n là gì -- nếu chúng có khả năng tạo hai ID theo thứ tự và thực hiện lặp đi lặp lại, họ có thể tìm ra n hoặc nếu họ có khả năng kiểm tra ID nào hợp lệ, họ có thể kiểm tra mọi số trong một số phạm vi nhỏ, để xem mức độ dày đặc của ID hợp lệ ID là, và tìm ra n từ đó.

Loại giải pháp duy nhất tôi có thể tìm thấy như sau: Trước tiên, hãy chuẩn bị trước một số công việc. Tuy nhiên, đối với nhiều giá trị ID mà bạn muốn tạo (giả sử 1 triệu), hãy lấy tất cả các số nguyên từ 1 đến 1 triệu và theo thứ tự, bắt đầu tính hàm băm của mỗi số nguyên cộng với một khóa bí mật. Cắt bớt hàm băm thành bất kỳ giá trị nào bạn cho là đủ ngắn. Tuy nhiên, với một khoảng thời gian cắt đủ ngắn, bạn sẽ thấy các xung đột. Vì vậy, mỗi khi bạn tạo một hàm băm cắt ngắn mới cho một số nguyên nhất định, hãy kiểm tra nó với các giá trị được tạo trước đó và nếu có xung đột, hãy thêm số nguyên đó vào danh sách L các số nguyên trong đó hàm băm của số nguyên đó xung đột với hàm băm của một số nguyên nhỏ hơn. (Vì vậy, trên thực tế, nếu kế hoạch của bạn là tạo 1 triệu ID, thì trong quá trình chuẩn bị của anh ấy, bạn sẽ phải sử dụng một chút 1 triệu số nguyên cuối cùng để bù cho những số nguyên mà bạn đã bỏ qua.)

Sau đó, trong thời gian chạy khi bạn tạo ID của mình, bạn chỉ cần bắt đầu với một bộ đếm số nguyên. Mỗi lần bạn tạo một ID mới, bạn tăng số nguyên và kiểm tra xem nó có trong danh sách L của bạn không, nếu có, bạn bỏ qua và chuyển sang số nguyên tiếp theo. (Điều này liên quan đến "tra cứu nhật ký", dường như vi phạm một trong các quy tắc đã nêu của tôi, nhưng điều tôi thực sự muốn làm là tránh phải kiểm tra từng giá trị ID mới với mọi giá trị được tạo cho đến nay; việc kiểm tra L sẽ nhanh hơn nhiều.) Và bạn có thể tinh chỉnh điều này để cân bằng (bạn thực hiện các giá trị băm bị cắt ngắn càng lâu thì L sẽ càng ngắn và do đó, lần kiểm tra sẽ càng ngắn mỗi khi bạn tạo ID mới; nhưng giá trị ID dài hơn có thể không được mong muốn).

Nhưng điều này cảm thấy giống như một hack. Có một cách tiêu chuẩn? Nếu không, bạn có thể nghĩ ra một cách tốt hơn?

kelalaka avatar
lá cờ in
Đối với khóa cố định, hãy mã hóa bằng chế độ AES-ECB. AES là một họ các hoán vị và một phím chọn một trong số chúng. Ngoài ra, tôi sẽ sử dụng SHA-512, SHAKE hoặc BLAKE-512, v.v. Việc tìm kiếm va chạm là điều không mong đợi, tuy nhiên, một khi bạn tìm thấy, bạn sẽ rất nổi tiếng!
poncho avatar
lá cờ my
@kelalaka: SHA-512? Vì vậy, bạn đang đề xuất id 512 bit (154 chữ số) ???
kelalaka avatar
lá cờ in
Bạn có nghĩ rằng mình có thể có nhiều hơn $2^{100}$ ID không?
poncho avatar
lá cờ my
@kelalaka: nếu bạn đang dựa vào khả năng chống va chạm của SHA-512, bạn cần xuất toàn bộ hàm băm - một hàm băm bị cắt ngắn sẽ không ngụ ý xung đột trong hàm băm ban đầu.
Bennett avatar
lá cờ ru
Vấn đề với việc sử dụng bất kỳ loại hàm băm nào để tạo ID cũng giống như vấn đề khi chỉ sử dụng các số ngẫu nhiên, như được mô tả trong tuyên bố vấn đề -- nếu bạn tránh xung đột bằng cách đơn giản là làm cho chúng dài ra, thì điều đó quá khó sử dụng và nếu bạn cắt ngắn chúng thành làm cho chúng ngắn hơn, bạn sẽ tăng khả năng xảy ra va chạm. Tôi đang tìm cách tránh va chạm mà không cần sử dụng các giá trị rất dài.
Điểm:2
lá cờ my

Cách hiệu quả nhất là sử dụng một Bảo toàn định dạng Thuật toán mã hóa; đó là một thuật toán hoán vị trên một tập hợp có kích thước tùy ý (ví dụ: một chuỗi gồm 10 chữ số thập phân).

Việc sử dụng nó sẽ đơn giản: bạn chọn một khóa ngẫu nhiên và lưu trữ nó; bạn cũng sẽ giữ một số thứ tự (ví dụ: ở cùng định dạng với đầu ra, bạn có thể bắt đầu bằng 0000000000). Sau đó, khi đến lúc tạo ID tiếp theo, bạn sẽ tăng số thứ tự và gửi số đó qua thuật toán FPE; đó là ID tiếp theo của bạn [1].

Bởi vì thuật toán FPE là một phép hoán vị, bạn sẽ không bao giờ tạo cùng một ID hai lần cho đến khi dãy số kết thúc; do đó, không có va chạm. Bạn có thể tạo ID càng ngắn càng tốt (thuật toán FPE hiện tại có vấn đề với khoảng trống thực sự nhỏ; nếu bạn giữ ID ở mức tối thiểu 6 chữ số, bạn sẽ an toàn). Và, bởi vì các thuật toán FPE là an toàn, bất kỳ ID nào cũng không cung cấp bất kỳ thông tin nào về bất kỳ ID nào khác (bao gồm cả thứ tự tạo tương đối).

Hạn chế: không có thư viện FPE phổ biến (theo như tôi biết). Để sử dụng, tôi muốn đề nghị FF1 từ tài liệu này; thực hiện điều đó từ đầu sẽ là một chút công việc (nhưng sẽ đáp ứng nhu cầu của bạn).


Một phương pháp kém hiệu quả hơn nhưng dễ thực hiện hơn là thực hiện một biến thể đối với những gì bạn đã đề xuất: giữ một danh sách ID mà bạn chưa chỉ định.

Tại đây, trong quá trình thiết lập, bạn sẽ khởi tạo danh sách tất cả các ID có thể có theo thứ tự tuần tự, chẳng hạn như 000000 đến 999999. Ngoài ra, bạn sẽ đặt giá trị N thành ID chưa được chỉ định cao nhất (trong ví dụ này, N = 999999).

Sau đó, khi đến lúc cấp ID mới, bạn sẽ chọn một số x ngẫu nhiên trong khoảng từ 0 đến N (bao gồm). Sau đó, bạn sẽ hoán đổi ID tại các chỉ số N và x (và nếu x=N, thì thao tác hoán đổi này không làm gì cả); sau đó, bạn sẽ xuất giá trị không có trong chỉ mục N (và sau đó giảm N).

Đó là nó; đây thực sự là Xáo bài Fisher-Yates, bạn có thể thực hiện việc này theo yêu cầu (như tôi đã viết) hoặc bạn có thể thực hiện tất cả việc xáo trộn tại thời điểm thiết lập (và chỉ cần đọc những thứ trong danh sách khi tạo ID).

Điều này kém hiệu quả hơn so với ý tưởng FPE - cả hai vì thiết lập liên quan nhiều hơn và bạn cần giữ một danh sách ID lớn xung quanh. Mặt khác, nó dễ triển khai hơn nhiều so với việc cố gắng triển khai FF1 từ đầu ...


[1]: Giữ nguyên định dạng Các thuật toán mã hóa cũng thực hiện 'tinh chỉnh'; bạn muốn giữ giá trị cố định đó (ví dụ: chuỗi trống); một tinh chỉnh cung cấp một dịch vụ mà mục đích sử dụng cụ thể của bạn không cần đến.

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.