如何創建一個以前不存在于串列中的隨機 16 位數字?
假設我有以下串列:
const nums = [7856328870763265, 0107654389657487];
我需要一個函式來生成隨機的 16 位數字,但這不會創建重復項。
我有以下幾點:
const val = Math.floor(1000 Math.random() * 9000).toString();
const random16digitnumber = val val val val;
console.log(random16digitnumber);
console.log(typeof random16digitnumber);
但恐怕在某個時候它會開始創建重復項。我在一個小型學校專案的 SQL 資料庫中使用 random16digitnumber 作為主鍵。
那么回到我的例子,我怎樣才能創建一個以前不存在于陣列中的隨機 16 位數字?
uj5u.com熱心網友回復:
我對 JavaScript 了解不多,但我會給你一個通用的解決方案。
您需要使用回圈陳述句來遍歷串列以檢查生成的數字是否在陣列中。如果它不在陣列中,則將其追加/推送到串列中。否則重新生成亂數。
可以用 php 或 python 撰寫它
uj5u.com熱心網友回復:
我會用行內評論來回答。我“按原樣”離開了你的演算法。你這樣做可能是有原因的;所以我只是實作了你想要的邏輯。
const nums = [7856328870763265, 0107654389657487];
const getNextRandomNumber = () => {
const val = Math.floor(1000 Math.random() * 9000).toString();
const candidate = val val val val;
// the generated number is part of the list;
// recursively call this function to generate another one
// (this works like a loop, just using call recursion)
// until a number is found that is not part of the list
// then the return below this if() is triggered
// and the "good" candidate is returned
if (nums[candidate]) {
return getNextRandomNumber();
}
// parseInt makes sure the string is converted back to number
// making sure we're using base 10, even if the first digit
// might be 0
return parseInt(candidate, 10);
}
// push() adds an element to the array
// the return value (100% guaranteed to be collision free random number)
// is added via the function call. The function logic makes sure
// it is absolutely unique
nums.push(getNextRandomNumber());
uj5u.com熱心網友回復:
如果您想要沒有重復的真正隨機性,那么您每次都需要檢查串列以確保它沒有被包含在內。最終這可能會拖累系統,但別無選擇。
如果您希望出現重復項的機會足夠小,以至于您的代碼可能會忽略它(除非您有驚人的數量),那么 GUID 可能是您最好的選擇……但這些遠遠超過 16 位數字。
但是,如果您希望隨機出現的數字是隨機的,盡管它們遠非隨機,那么一個簡單的演算法將按10^16隨機順序為您提供所有數字。我們可以通過將后續數字作為當前數字的線性變換來實作這一點。我們可以將當前值乘以某個數字,a然后添加另一個值b,然后取最后 16 位數字來獲得下一個值。只要a和b沒有共同的真因數,也沒有任何與 10^16 共同的真因數,這個程序就會9999999999999999以看似隨機的順序回圈從零到所有數字。
確保沒有公因數的最簡單方法是選擇兩個 16 位素數,我們可以在https://bigprimes.org/ 之類的網站上進行。
如果我們可以保持或輕松查找上次使用的 id,那么我們可以這樣寫:
const a = BigInt ( '7791448648907857')
const b = BigInt ( '2320712743817497')
const c = BigInt ('10000000000000000')
const nextId = (previousId) =>
((a * BigInt(previousId) b) % c)
.toString () .padStart ('0', 16)
const lastRecord = {id: '1234567890123456', more: 'fields'}
console .log (nextId (lastRecord .id))
如果我們不能輕松跟蹤最后一個 id,但可以保留一個順序計數器,例如n,我們總是可以使用公式生成它
id_n = (a ** n b * ((a ** n - 1) / (a - 1))) % c
這將涉及有效管理模冪運算,但這是一個很好解決的問題,并且很容易實作。
不要忘記,這不僅在密碼學上不安全,而且遠非隨機。但它會給你看起來隨機的數字而不會重復。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/313559.html
標籤:javascript 数组 算法 随机的
上一篇:中間有必填詞的字梯問題
